<?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" version="2.0"><channel><title><![CDATA[Hemant's blog]]></title><description><![CDATA[My passion for creating beautiful websites led me to become a fellow front-end developer.]]></description><link>https://blog.hemant.lol</link><generator>RSS for Node</generator><lastBuildDate>Mon, 08 Jun 2026 13:41:59 GMT</lastBuildDate><atom:link href="https://blog.hemant.lol/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Tailwind gets even cooler with tailwind signals]]></title><description><![CDATA[If you're into web design, you've probably heard of Tailwind CSS, a handy toolkit that makes styling websites a breeze. Well, get ready for something even cooler: Tailwind Signals. It's like adding a turbo boost to your CSS skills.
So, as we all know...]]></description><link>https://blog.hemant.lol/signals</link><guid isPermaLink="true">https://blog.hemant.lol/signals</guid><category><![CDATA[tailwindcss-signals]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[CSS]]></category><category><![CDATA[scss]]></category><category><![CDATA[signals]]></category><dc:creator><![CDATA[Hemant]]></dc:creator><pubDate>Tue, 16 Apr 2024 18:23:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1713291707801/997c18e7-60d2-4cbe-b1f8-5c8de03521e9.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you're into web design, you've probably heard of Tailwind CSS, a handy toolkit that makes styling websites a breeze. Well, get ready for something even cooler: Tailwind Signals. It's like adding a turbo boost to your CSS skills.</p>
<p>So, as we all know about Pseudo classes in Tailwind CSS enable developers to apply styles to elements based on various states or interactions, such as hover, focus, and active states. With just a few special words, you can make your website more interactive and engaging without needing to write lots of extra code!</p>
<p>In Tailwind CSS, groups and peers are two concepts that build upon pseudo-classes:</p>
<ol>
<li><p><strong>Group Relationship</strong>: When one element is nested within another, creating a parent-child relationship, they form a group. Styling applied to the parent (group) can affect the child (nested) elements, providing powerful control over the entire group’s appearance.  </p>
<p> By adding the <code>group</code> class to a parent element, developers can target nested elements within the group using pseudo classes like <code>group-hover</code>. This enables changes in appearance when interacting with the parent element, cascading down to its children.</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
   <span class="hljs-keyword">return</span> (
     &lt;&gt;
       &lt;div className=<span class="hljs-string">"group"</span>&gt;
         &lt;div className=<span class="hljs-string">"group-hover:..."</span> /&gt;
       &lt;/div&gt;
     &lt;/&gt;
   );
 };
</code></pre>
</li>
<li><p><strong>Peer Relationship</strong>: Elements that are siblings or on the same level within the DOM hierarchy are considered peers. They share a peer relationship, allowing for synchronized styling based on interactions with one element affecting the others.  </p>
<p> Similarly, applying the <code>peer</code> class to sibling elements allows for synchronized styling based on interactions with any peer element. Utilizing pseudo classes such as <code>peer-hover</code>, developers can achieve coordinated effects across sibling elements without the need for complex JavaScript logic.</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
   <span class="hljs-keyword">return</span> (
     &lt;&gt;
       &lt;div className=<span class="hljs-string">"peer"</span> /&gt;
       &lt;div className=<span class="hljs-string">"peer-hover:bg-red-500"</span> /&gt;
     &lt;/&gt;
   );
 };
</code></pre>
</li>
</ol>
<p>Now which problems do signals actually solves. Imagine we have an email input field and a corresponding div element below it. Even without JavaScript, we can make the div react to the input's state by giving it a classname like <code>peer</code> when the input is invalid. We can style this div to be visible and display a message like "invalid input" if you type in something wrong, like "123" instead of an email. Signals build upon this concept. And they do a really good job at that.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    &lt;&gt;
      &lt;input className=<span class="hljs-string">"peer"</span> <span class="hljs-keyword">type</span>=<span class="hljs-string">"email"</span> /&gt;
      &lt;div className=<span class="hljs-string">"peer-invalid:block hidden"</span> /&gt;
    &lt;/&gt;
  );
};
</code></pre>
<p>Here's how it works: you create what's called a "signal" on a parent element, like a div. This signal acts as a trigger that tells other elements, like buttons or text fields, to do something when it's activated. For example, you can set up a signal that says, "Hey, if this box is checked, change the background color of the nested element from red to green."</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    &lt;&gt;
      &lt;input className=<span class="hljs-string">"peer"</span> <span class="hljs-keyword">type</span>=<span class="hljs-string">"checkbox"</span> /&gt; 👈🏻 check/uncheck here
      &lt;div className=<span class="hljs-string">"peer-checked:signal"</span>&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;div className=<span class="hljs-string">"signal:bg-green-500 bg-red-500 p-1 text-white"</span>&gt;
              nested div
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/&gt;
  );
};
</code></pre>
<p>The best part? You can do all of this with just CSS. No need for fancy JavaScript tricks or complicated code. Tailwind Signals simplifies the whole process, making it easier for you to create dynamic, responsive websites without pulling your hair out over code.</p>
<p>But, like any new technology, Tailwind Signals isn't perfect. It's still in the experimental stage, and not all web browsers support it yet. So, while it's super cool, you might have to wait a bit before you can use it everywhere.</p>
<p>For more information please check out: <a target="_blank" href="https://www.npmjs.com/package/tailwindcss-signals">https://www.npmjs.com/package/tailwindcss-signals</a></p>
<p>CC: <a target="_blank" href="https://www.youtube.com/watch?v=SmOstmWBneE">https://www.youtube.com/watch?v=SmOstmWBneE</a></p>
]]></content:encoded></item><item><title><![CDATA[A brief introduction to GraphQL]]></title><description><![CDATA[What is GraphQL?
GraphQL is a query language and runtime for APIs. It was created by Facebook and open-sourced in 2015.
In simple terms, GraphQL is:

A query language: It provides a syntax for clients to define the exact data they need from an API.

...]]></description><link>https://blog.hemant.lol/graphql</link><guid isPermaLink="true">https://blog.hemant.lol/graphql</guid><category><![CDATA[GraphQL]]></category><category><![CDATA[REST API]]></category><category><![CDATA[APIs]]></category><category><![CDATA[Facebook]]></category><category><![CDATA[graphql-mutation]]></category><dc:creator><![CDATA[Hemant]]></dc:creator><pubDate>Mon, 25 Sep 2023 10:47:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1695634706213/e740d533-6d26-48ab-a883-595e150c71bf.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-what-is-graphql">What is GraphQL?</h2>
<p>GraphQL is a query language and runtime for APIs. It was created by Facebook and open-sourced in 2015.</p>
<p>In simple terms, GraphQL is:</p>
<ul>
<li><p>A query language: It provides a syntax for clients to define the exact data they need from an API.</p>
</li>
<li><p>A runtime: It runs on the server and provides an API layer over your existing data.</p>
</li>
</ul>
<p>Some key benefits of GraphQL are:</p>
<ul>
<li><p>Efficiency: GraphQL queries fetch only the required data fields, avoiding over- or under-fetching of data.</p>
</li>
<li><p>Flexibility: GraphQL queries can fetch data from multiple data sources in a single request.</p>
</li>
<li><p>Strong typing: GraphQL defines a type system for the data, providing runtime validation of queries.</p>
</li>
<li><p>Self-documenting: GraphQL exposes introspection, allowing clients to discover the graph structure.</p>
</li>
</ul>
<h2 id="heading-how-does-graphql-work">How Does GraphQL Work?</h2>
<p>GraphQL provides a single endpoint for the API, typically <code>/graphql</code>. Clients make requests to this endpoint to fetch the data they need.</p>
<p>A GraphQL query specifies the exact data fields required from the API. For example:</p>
<pre><code class="lang-graphql">{
  user(<span class="hljs-symbol">id:</span> <span class="hljs-number">1</span>) {
    firstName
    lastName
  }
}
</code></pre>
<p>This query will fetch only the <code>firstName</code> and <code>lastName</code> fields for the user with ID <code>1</code>.</p>
<p>The GraphQL schema defines the types and fields available in the API. Resolvers are functions that fetch the actual data when a query is executed.</p>
<p>When a query is received, the GraphQL runtime:</p>
<ol>
<li><p>Validates the query against the schema</p>
</li>
<li><p>Executes the resolvers for the fields in the query</p>
</li>
<li><p>Returns the data in a JSON response</p>
</li>
</ol>
<h2 id="heading-graphql-vs-rest">GraphQL vs REST</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695634167214/32c46263-9baa-4eb6-a205-fb684f70c5b7.jpeg" alt class="image--center mx-auto" /></p>
<p>GraphQL and REST are two different API architectures:</p>
<ul>
<li><p>REST uses HTTP methods and URL paths to access data. It returns full resources in responses.</p>
</li>
<li><p>GraphQL uses a query language and a single endpoint. It returns only the requested fields in responses.</p>
</li>
</ul>
<p>Some advantages of GraphQL over REST:</p>
<ul>
<li><p>Efficiency: GraphQL returns only the requested data, while REST often over- or under-fetches data.</p>
</li>
<li><p>Flexibility: GraphQL queries can fetch data from multiple sources in one request.</p>
</li>
<li><p>Versioning: GraphQL uses a field-level approach to versioning, making it easier to evolve APIs over time.</p>
</li>
</ul>
<h2 id="heading-how-does-graphql-work-1">How does GraphQL work?</h2>
<p>Curious about how GraphQL efficiently retrieves precisely the data you need, without any excess?</p>
<p>Essentially, using GraphQL involves creating a type system that allows you to execute targeted queries. Each type can contain fields and functions that determine the available operations. When combined, these components form a GraphQL service.</p>
<p>When a client sends a query to the GraphQL service, an integrated query parser utilizes your schema to validate the incoming query. If no errors are found, it executes the associated functions for the requested fields and returns a result.</p>
<h2 id="heading-ia"> </h2>
<p>What sets GraphQL apart and makes it special?</p>
<p>GraphQL is special for several reasons. Firstly, it simplifies the process of querying data by allowing clients to request exactly what they need in a single request. This saves time and resources because the server doesn't have to make multiple requests to fulfill the client's requirements.</p>
<p>Secondly, GraphQL supports real-time subscriptions, which means that clients can receive updates whenever a specific operation is performed on the server. This enables applications to be more responsive, providing users with up-to-date data as it changes in near real-time.</p>
<p>Lastly, GraphQL is designed to be language-agnostic, meaning it can be used with any programming language. This flexibility makes it easier for developers to integrate GraphQL into their existing applications and quickly build powerful APIs without being restricted to a specific language.</p>
<p>If you enjoyed reading this blog, we would greatly appreciate your support by giving it a like. Your feedback and engagement mean a lot to us. Thank you for taking the time to read and engage with our content!</p>
]]></content:encoded></item><item><title><![CDATA[A Beginner's Introduction to Apache Kafka]]></title><description><![CDATA[Apache Kafka is a system that helps transfer data in real-time. It is commonly used in modern applications where events play a crucial role. For example, when a customer places an order on a website, the order service needs to inform other services a...]]></description><link>https://blog.hemant.lol/kafka</link><guid isPermaLink="true">https://blog.hemant.lol/kafka</guid><category><![CDATA[kafka]]></category><category><![CDATA[apache]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[throughput]]></category><dc:creator><![CDATA[Hemant]]></dc:creator><pubDate>Fri, 08 Sep 2023 16:43:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1694191325250/58d5980d-97d4-4936-879a-f9971f177229.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Apache Kafka is a system that helps transfer data in real-time. It is commonly used in modern applications where events play a crucial role. For example, when a customer places an order on a website, the order service needs to inform other services about the order's status. This is done by generating an event that triggers actions in other services. Apache Kafka acts as a messaging system that receives data from source systems and sends it to target systems.</p>
<p>Kafka is a distributed system that consists of servers and clients communicating through a high-performance TCP network protocol. It is an open-source system created by LinkedIn and is maintained by companies like LinkedIn, Confluent, IBM, and others. Many well-known companies, including LinkedIn, Airbnb, and Netflix, use Kafka for their data transfer needs.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694185984757/2d5611cc-394f-4165-be0d-9bf3bfc57411.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-why-should-we-use-apache-kafka"><strong>Why should we use Apache Kafka?</strong></h1>
<ol>
<li><p><strong>Distributed Streaming System:</strong> Apache Kafka is a messaging system that consists of multiple servers working together. These servers form a cluster and can be set up anywhere as needed.</p>
</li>
<li><p><strong>Fault Tolerant System:</strong> Kafka uses replication to ensure fault tolerance. Data is replicated across all servers, so if one node fails, data can still be processed from other nodes.</p>
</li>
<li><p><strong>Scalability:</strong> Kafka is highly scalable. It allows for fast and automatic recovery in case of node failure. You can increase the number of brokers and consumers to handle high loads and increasing demand.</p>
</li>
<li><p><strong>High Performance:</strong> Kafka is efficient in handling a large volume of data. It can process millions of messages per second with high throughput and low latency.</p>
</li>
</ol>
<h1 id="heading-kafka-architecture"><strong>Kafka Architecture</strong></h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694186746870/db3c09ea-5993-4c49-a942-b23873b6c146.jpeg" alt class="image--center mx-auto" /></p>
<p>The picture above explains how Kafka is set up. Now, let's talk about each part of the Kafka diagram in simple terms.</p>
<p><strong>Kafka Cluster</strong>:<br />A Kafka cluster is a group of Kafka brokers. Think of a broker as a server that sends and receives data. In Kafka, brokers are called brokers because they handle data. Each broker in the cluster has a unique ID.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694187315060/d8d484aa-1e59-433d-b795-6dea9c8fee98.png" alt class="image--center mx-auto" /></p>
<p><strong>Kafka Broker:</strong><br />Brokers in Kafka have different topics. A topic is like a stream of data in the Kafka cluster. Each topic is divided into partitions. Topics are identified by their names. The partitions of a topic are spread evenly across the brokers in the cluster, which helps Kafka handle large amounts of data. Brokers are responsible for copying data to different partitions. Each broker in the Kafka cluster has all the information about the entire cluster. Brokers receive messages from producers and store them on disk. A Kafka broker is also called a bootstrap server.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694187664230/a3ab51dc-4c00-4dd6-a0c3-456d1545cbe4.webp" alt class="image--center mx-auto" /></p>
<p><strong>Producers:</strong><br />In the Kafka system, there are several producers that send data to Kafka topics. Producers are smart and can determine which partitions to write data to. If a Kafka server with a partition fails, the producers can recover automatically. Before sending messages to Kafka topics, producers use message serializers to convert the messages into a suitable format.</p>
<blockquote>
<p>In Kafka, data is sent and received as bytes. Producers convert the data into bytes before sending it to Kafka, and consumers receive the data as bytes. This byte-based communication allows Kafka to handle different types of data effectively and ensures that producers and consumers can work together seamlessly.</p>
</blockquote>
<p><strong>Consumers:</strong><br />Consumers in Kafka are responsible for reading messages from Kafka topics. They use a pull model to retrieve data from specific partitions within a topic. Consumers are organized into consumer groups, and each group can have multiple consumers reading data from a topic.</p>
<p>When reading data, a consumer starts from a lower offset and reads messages in order up to a higher offset within a partition. However, if a consumer is reading from multiple partitions, the order of messages is not guaranteed. Kafka sends data to consumers in the form of bytes. To make the data usable, consumers use message deserializers to convert the bytes back into their original object format.</p>
<p><strong>ZooKeeper:</strong><br />In the Kafka ecosystem, there is another important component called ZooKeeper. ZooKeeper is responsible for managing the metadata of the Kafka system. It helps Kafka by informing producers and consumers about the addition or removal of Kafka brokers in the cluster. Additionally, Kafka brokers rely on ZooKeeper to determine the leader of each partition. In summary, ZooKeeper plays a crucial role in coordinating and maintaining the overall stability and functionality of the Kafka system.</p>
<h1 id="heading-kafka-with-nodejs"><strong>Kafka with Node.js:</strong></h1>
<p><strong>Prerequisites:</strong></p>
<ul>
<li><p>Node.JS Intermediate level</p>
</li>
<li><p>Experience with designing distributed systems</p>
</li>
<li><p>Node.js: <a target="_blank" href="https://nodejs.org/en">Download Node.JS</a></p>
</li>
<li><p>Docker: <a target="_blank" href="https://www.docker.com/">Download Docker</a></p>
</li>
<li><p>VsCode: <a target="_blank" href="https://code.visualstudio.com/">Download VSCode</a></p>
</li>
</ul>
<blockquote>
<p>Refer this <a target="_blank" href="https://gist.github.com/piyushgarg-dev/32cadf6420c452b66a9a6d977ade0b01"><em>gist</em></a> for the code and all commands which we are going to use!</p>
</blockquote>
<p><strong>Start ZooKeeper:</strong> Kafka uses ZooKeeper for coordination, so you need to start ZooKeeper before starting Kafka. ZooKeeper manages the configuration, synchronization, and leader election for Kafka.</p>
<ul>
<li>Start Zookeper Container and expose PORT <code>2181</code>.</li>
</ul>
<pre><code class="lang-bash">$ docker run -p 2181:2181 zookeeper
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
2023-09-08 16:07:19,761 [myid:] - INFO  [main:o.a.z.s.q.QuorumPeerConfig@177] - Reading configuration from: /conf/zoo.cfg
2023-09-08 16:07:19,769 [myid:] - INFO  [main:o.a.z.s.q.QuorumPeerConfig@431] - clientPort is not <span class="hljs-built_in">set</span>
2023-09-08 16:07:19,769 [myid:] - INFO  [main:o.a.z.s.q.QuorumPeerConfig@444] - secureClientPort is not <span class="hljs-built_in">set</span>
2023-09-08 16:07:19,770 [myid:] - INFO  [main:o.a.z.s.q.QuorumPeerConfig@460] - observerMasterPort is not <span class="hljs-built_in">set</span>
2023-09-08 16:07:19,770 [myid:] - INFO  [main:o.a.z.s.q.QuorumPeerConfig@477] - metricsProvider.className is org.apache.zookeeper.metrics.impl.DefaultMetricsProvider
2023-09-08 16:07:19,793 [myid:] - ERROR [main:o.a.z.s.q.QuorumPeerConfig@702] - Invalid configuration, only one server specified (ignoring)
2023-09-08 16:07:19,799 [myid:1] - INFO  [main:o.a.z.s.DatadirCleanupManager@78] - autopurge.snapRetainCount <span class="hljs-built_in">set</span> to 3
2023-09-08 16:07:19,799 [myid:1] - INFO  [main:o.a.z.s.DatadirCleanupManager@79] - autopurge.purgeInterval <span class="hljs-built_in">set</span> to 0
2023-09-08 16:07:19,799 [myid:1] - INFO  [main:o.a.z.s.DatadirCleanupManager@101] - Purge task is not scheduled.
2023-09-08 16:07:19,799 [myid:1] - WARN  [main:o.a.z.s.q.QuorumPeerMain@139] - Either no config or no quorum defined <span class="hljs-keyword">in</span> config, running <span class="hljs-keyword">in</span> standalone mode
2023-09-08 16:07:19,805 [myid:1] - INFO  [main:o.a.z.j.ManagedUtil@46] - Log4j 1.2 jmx support not found; jmx disabled.
2023-09-08 16:07:19,808 [myid:1] - INFO  [main:o.a.z.s.q.QuorumPeerConfig@177] - Reading configuration from: /conf/zoo.cfg
2023-09-08 16:07:19,811 [myid:1] - INFO  [main:o.a.z.s.q.QuorumPeerConfig@431] - clientPort is not <span class="hljs-built_in">set</span>
2023-09-08 16:07:19,811 [myid:1] - INFO  [main:o.a.z.s.q.QuorumPeerConfig@444] - secureClientPort is not <span class="hljs-built_in">set</span>
2023-09-08 16:07:19,811 [myid:1] - INFO  [main:o.a.z.s.q.QuorumPeerConfig@460] - observerMasterPort is not <span class="hljs-built_in">set</span>
2023-09-08 16:07:19,811 [myid:1] - INFO  [main:o.a.z.s.q.QuorumPeerConfig@477] - metricsProvider.className is org.apache.zookeeper.metrics.impl.DefaultMetricsProvider
2023-09-08 16:07:19,811 [myid:1] - ERROR [main:o.a.z.s.q.QuorumPeerConfig@702] - Invalid configuration, only one server specified (ignoring)
2023-09-08 16:07:19,812 [myid:1] - INFO  [main:o.a.z.s.ZooKeeperServerMain@123] - Starting server
2023-09-08 16:07:19,849 [myid:1] - INFO  [main:o.a.z.s.ServerMetrics@64] - ServerMetrics initialized with provider org.apache.zookeeper.metrics.impl.DefaultMetricsProvider@4218d6a3
2023-09-08 16:07:19,861 [myid:1] - INFO  [main:o.a.z.s.a.DigestAuthenticationProvider@51] - ACL digest algorithm is: SHA1
2023-09-08 16:07:19,862 [myid:1] - INFO  [main:o.a.z.s.a.DigestAuthenticationProvider@65] - zookeeper.DigestAuthenticationProvider.enabled = <span class="hljs-literal">true</span>
2023-09-08 16:07:19,877 [myid:1] - INFO  [main:o.a.z.s.p.FileTxnSnapLog@124] - zookeeper.snapshot.trust.empty : <span class="hljs-literal">false</span>
2023-09-08 16:07:19,922 [myid:1] - INFO  [main:o.a.z.ZookeeperBanner@42] -
2023-09-08 16:07:19,922 [myid:1] - INFO  [main:o.a.z.ZookeeperBanner@42] -   ______                  _

2023-09-08 16:07:19,922 [myid:1] - INFO  [main:o.a.z.ZookeeperBanner@42] -  |___  /                 | |

2023-09-08 16:07:19,922 [myid:1] - INFO  [main:o.a.z.ZookeeperBanner@42] -     / /    ___     ___   | | __   ___    ___   _ __     ___   _ __
2023-09-08 16:07:19,922 [myid:1] - INFO  [main:o.a.z.ZookeeperBanner@42] -    / /    / _ \   / _ \  | |/ /  / _ \  / _ \ | <span class="hljs-string">'_ \   / _ \ | '</span>__|
2023-09-08 16:07:19,922 [myid:1] - INFO  [main:o.a.z.ZookeeperBanner@42] -   / /__  | (_) | | (_) | |   &lt;  |  __/ |  __/ | |_) | |  __/ | |
2023-09-08 16:07:19,922 [myid:1] - INFO  [main:o.a.z.ZookeeperBanner@42] -  /_____|  \___/   \___/  |_|\_\  \___|  \___| | .__/   \___| |_|
2023-09-08 16:07:19,923 [myid:1] - INFO  [main:o.a.z.ZookeeperBanner@42] -
 | |
2023-09-08 16:07:19,923 [myid:1] - INFO  [main:o.a.z.ZookeeperBanner@42] -
 |_|
</code></pre>
<p><strong>Start Kafka</strong>: Once ZooKeeper is up and running, you can start Kafka. Kafka consists of multiple components, including brokers, topics, producers, and consumers.</p>
<ul>
<li>Start Kafka Container, expose PORT <code>9092</code> and setup ENV variables.</li>
</ul>
<pre><code class="lang-bash">$ docker run -p 9092:9092 \
-e KAFKA_ZOOKEEPER_CONNECT=&lt;PRIVATE_IP&gt;:2181 \
-e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://&lt;PRIVATE_IP&gt;:9092 \
-e KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 \
confluentinc/cp-kafka
</code></pre>
<p><strong>PRIVATE_IP</strong> is the unique address assigned to your computer on the local network. You can find this address by running the <code>ipconfig</code> command in the terminal or command prompt.</p>
<h3 id="heading-lets-move-on-to-the-code-part">Let's move on to the code part:</h3>
<ol>
<li><p>Now open up your sample folder in your code editor.</p>
</li>
<li><p>Initializing a node.js app with <code>yarn init</code> and press enter for all the default settings.</p>
</li>
<li><p>Install <code>kafkajs</code> as your dependency.</p>
</li>
</ol>
<pre><code class="lang-powershell">npm install kafkajs
</code></pre>
<p>Now create a <code>client.js</code> file in the root directory of your app and pase the below code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { Kafka } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"kafkajs"</span>);

<span class="hljs-built_in">exports</span>.kafka = <span class="hljs-keyword">new</span> Kafka({
  <span class="hljs-attr">clientId</span>: <span class="hljs-string">"my-app"</span>,
  <span class="hljs-attr">brokers</span>: [<span class="hljs-string">"&lt;YOUR_PRIVATE_IP&gt;:9092"</span>],
});
</code></pre>
<p><strong>Create a Topic:</strong> Topics are the core abstraction in Kafka. They represent a particular stream of records. You can create a topic using the Kafka command-line tools or programmatically using the Kafka API.</p>
<p>Create a <code>admin.js</code> file and paste the below code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { kafka } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./client"</span>);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">init</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> admin = kafka.admin();
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Admin connecting..."</span>);
  admin.connect();
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Adming Connection Success..."</span>);

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Creating Topic [rider-updates]"</span>);
  <span class="hljs-keyword">await</span> admin.createTopics({
    <span class="hljs-attr">topics</span>: [
      {
        <span class="hljs-attr">topic</span>: <span class="hljs-string">"rider-updates"</span>,
        <span class="hljs-attr">numPartitions</span>: <span class="hljs-number">2</span>,
      },
    ],
  });
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Topic Created Success [rider-updates]"</span>);

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Disconnecting Admin.."</span>);
  <span class="hljs-keyword">await</span> admin.disconnect();
}

init();
</code></pre>
<p><strong>Produce Messages:</strong> Producers are responsible for publishing messages to Kafka topics. You can create a producer application that sends messages to a specific topic. Messages can be in any format, such as JSON, Avro, or plain text.</p>
<p>Create a <code>producer.js</code> file and paste the below code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { kafka } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./client"</span>);
<span class="hljs-keyword">const</span> readline = <span class="hljs-built_in">require</span>(<span class="hljs-string">"readline"</span>);

<span class="hljs-keyword">const</span> rl = readline.createInterface({
  <span class="hljs-attr">input</span>: process.stdin,
  <span class="hljs-attr">output</span>: process.stdout,
});

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">init</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> producer = kafka.producer();

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Connecting Producer"</span>);
  <span class="hljs-keyword">await</span> producer.connect();
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Producer Connected Successfully"</span>);

  rl.setPrompt(<span class="hljs-string">"&gt; "</span>);
  rl.prompt();

  rl.on(<span class="hljs-string">"line"</span>, <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">line</span>) </span>{
    <span class="hljs-keyword">const</span> [riderName, location] = line.split(<span class="hljs-string">" "</span>);
    <span class="hljs-keyword">await</span> producer.send({
      <span class="hljs-attr">topic</span>: <span class="hljs-string">"rider-updates"</span>,
      <span class="hljs-attr">messages</span>: [
        {
          <span class="hljs-attr">partition</span>: location.toLowerCase() === <span class="hljs-string">"north"</span> ? <span class="hljs-number">0</span> : <span class="hljs-number">1</span>,
          <span class="hljs-attr">key</span>: <span class="hljs-string">"location-update"</span>,
          <span class="hljs-attr">value</span>: <span class="hljs-built_in">JSON</span>.stringify({ <span class="hljs-attr">name</span>: riderName, location }),
        },
      ],
    });
  }).on(<span class="hljs-string">"close"</span>, <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">await</span> producer.disconnect();
  });
}

init();
</code></pre>
<p><strong>Consume Messages:</strong> Consumers read messages from Kafka topics. You can create a consumer application that subscribes to a topic and processes the incoming messages. Consumers can be single-threaded or multi-threaded, depending on your requirements.</p>
<p>Create a <code>consumer.js</code> file and paste the below code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { kafka } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./client"</span>);
<span class="hljs-keyword">const</span> group = process.argv[<span class="hljs-number">2</span>];

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">init</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> consumer = kafka.consumer({ <span class="hljs-attr">groupId</span>: group });
  <span class="hljs-keyword">await</span> consumer.connect();

  <span class="hljs-keyword">await</span> consumer.subscribe({ <span class="hljs-attr">topics</span>: [<span class="hljs-string">"rider-updates"</span>], <span class="hljs-attr">fromBeginning</span>: <span class="hljs-literal">true</span> });

  <span class="hljs-keyword">await</span> consumer.run({
    <span class="hljs-attr">eachMessage</span>: <span class="hljs-keyword">async</span> ({ topic, partition, message, heartbeat, pause }) =&gt; {
      <span class="hljs-built_in">console</span>.log(
        <span class="hljs-string">`<span class="hljs-subst">${group}</span>: [<span class="hljs-subst">${topic}</span>]: PART:<span class="hljs-subst">${partition}</span>:`</span>,
        message.value.toString()
      );
    },
  });
}

init();
</code></pre>
<p><strong>Now let's try running our code:</strong></p>
<ul>
<li>Run the <code>admin.js</code> file first.</li>
</ul>
<pre><code class="lang-bash">$ node .\admin.js
Admin connecting...
Adming Connection Success...
Creating Topic [rider-updates]
Topic Created Success [rider-updates]
Disconnecting Admin..
</code></pre>
<ul>
<li>Let's try producing messages by running <code>producer.js</code> file.</li>
</ul>
<pre><code class="lang-bash">$ node .\producer.js
{<span class="hljs-string">"level"</span>:<span class="hljs-string">"WARN"</span>,<span class="hljs-string">"timestamp"</span>:<span class="hljs-string">"2023-09-08T16:27:32.852Z"</span>,<span class="hljs-string">"logger"</span>:<span class="hljs-string">"kafkajs"</span>,<span class="hljs-string">"message"</span>:<span class="hljs-string">"KafkaJS v2.0.0 switched default partitioner. To retain the same partitioning behavior as in previous versions, create the producer with the option \"createPartitioner: Partitioners.LegacyPartitioner\". See the migration guide at https://kafka.js.org/docs/migration-guide-v2.0.0#producer-new-default-partitioner for details. Silence this warning by setting the environment variable \"KAFKAJS_NO_PARTITIONER_WARNING=1\""</span>}
Connecting Producer
Producer Connected Successfully
&gt; tom south
&gt; jerry north
</code></pre>
<ul>
<li>Now let's see if we can get our produced messages or not by running <code>consumer.js</code> file.</li>
</ul>
<pre><code class="lang-bash">$ node consumer.js user-1
{<span class="hljs-string">"level"</span>:<span class="hljs-string">"INFO"</span>,<span class="hljs-string">"timestamp"</span>:<span class="hljs-string">"2023-09-08T16:29:58.307Z"</span>,<span class="hljs-string">"logger"</span>:<span class="hljs-string">"kafkajs"</span>,<span class="hljs-string">"message"</span>:<span class="hljs-string">"[Consumer] Starting"</span>,<span class="hljs-string">"groupId"</span>:<span class="hljs-string">"user-1"</span>}
{<span class="hljs-string">"level"</span>:<span class="hljs-string">"ERROR"</span>,<span class="hljs-string">"timestamp"</span>:<span class="hljs-string">"2023-09-08T16:29:58.415Z"</span>,<span class="hljs-string">"logger"</span>:<span class="hljs-string">"kafkajs"</span>,<span class="hljs-string">"message"</span>:<span class="hljs-string">"[Connection] Response GroupCoordinator(key: 10, version: 2)"</span>,<span class="hljs-string">"broker"</span>:<span class="hljs-string">"192.168.0.101:9092"</span>,<span class="hljs-string">"clientId"</span>:<span class="hljs-string">"my-app"</span>,<span class="hljs-string">"error"</span>:<span class="hljs-string">"The group coordinator is not available"</span>,<span class="hljs-string">"correlationId"</span>:2,<span class="hljs-string">"size"</span>:55}
{<span class="hljs-string">"level"</span>:<span class="hljs-string">"ERROR"</span>,<span class="hljs-string">"timestamp"</span>:<span class="hljs-string">"2023-09-08T16:29:58.936Z"</span>,<span class="hljs-string">"logger"</span>:<span class="hljs-string">"kafkajs"</span>,<span class="hljs-string">"message"</span>:<span class="hljs-string">"[Connection] Response GroupCoordinator(key: 10, version: 2)"</span>,<span class="hljs-string">"broker"</span>:<span class="hljs-string">"192.168.0.101:9092"</span>,<span class="hljs-string">"clientId"</span>:<span class="hljs-string">"my-app"</span>,<span class="hljs-string">"error"</span>:<span class="hljs-string">"The group coordinator is not available"</span>,<span class="hljs-string">"correlationId"</span>:3,<span class="hljs-string">"size"</span>:55}
{<span class="hljs-string">"level"</span>:<span class="hljs-string">"ERROR"</span>,<span class="hljs-string">"timestamp"</span>:<span class="hljs-string">"2023-09-08T16:29:59.634Z"</span>,<span class="hljs-string">"logger"</span>:<span class="hljs-string">"kafkajs"</span>,<span class="hljs-string">"message"</span>:<span class="hljs-string">"[Connection] Response GroupCoordinator(key: 10, version: 2)"</span>,<span class="hljs-string">"broker"</span>:<span class="hljs-string">"192.168.0.101:9092"</span>,<span class="hljs-string">"clientId"</span>:<span class="hljs-string">"my-app"</span>,<span class="hljs-string">"error"</span>:<span class="hljs-string">"The group coordinator is not available"</span>,<span class="hljs-string">"correlationId"</span>:4,<span class="hljs-string">"size"</span>:55}
{<span class="hljs-string">"level"</span>:<span class="hljs-string">"INFO"</span>,<span class="hljs-string">"timestamp"</span>:<span class="hljs-string">"2023-09-08T16:30:04.361Z"</span>,<span class="hljs-string">"logger"</span>:<span class="hljs-string">"kafkajs"</span>,<span class="hljs-string">"message"</span>:<span class="hljs-string">"[ConsumerGroup] Consumer has joined the group"</span>,<span class="hljs-string">"groupId"</span>:<span class="hljs-string">"user-1"</span>,<span class="hljs-string">"memberId"</span>:<span class="hljs-string">"my-app-a98b5172-1bd0-4602-b0ed-7d02b25ef2ee"</span>,<span class="hljs-string">"leaderId"</span>:<span class="hljs-string">"my-app-a98b5172-1bd0-4602-b0ed-7d02b25ef2ee"</span>,<span class="hljs-string">"isLeader"</span>:<span class="hljs-literal">true</span>,<span class="hljs-string">"memberAssignment"</span>:{<span class="hljs-string">"rider-updates"</span>:[0,1]},<span class="hljs-string">"groupProtocol"</span>:<span class="hljs-string">"RoundRobinAssigner"</span>,<span class="hljs-string">"duration"</span>:6051}
user-1: [rider-updates]: PART:1: {<span class="hljs-string">"name"</span>:<span class="hljs-string">"tom"</span>,<span class="hljs-string">"location"</span>:<span class="hljs-string">"south"</span>}
user-1: [rider-updates]: PART:0: {<span class="hljs-string">"name"</span>:<span class="hljs-string">"jerry"</span>,<span class="hljs-string">"location"</span>:<span class="hljs-string">"north"</span>}
</code></pre>
<h3 id="heading-congratulations"><strong>Congratulations!</strong></h3>
<p>We're successfully getting the produced messages as consumers!</p>
<p>If you want to understand Kafka in more detail then go and check their <a target="_blank" href="https://kafka.apache.org/documentation/"><em>docs</em></a>.</p>
<p>Also, you can check out this awesome <a target="_blank" href="https://www.youtube.com/watch?v=ZJJHm_bd9Zo"><em>video</em></a> by <a class="user-mention" href="https://hashnode.com/@piyushgarg">Piyush Garg</a> about Kafka with an easy explanation!!</p>
]]></content:encoded></item><item><title><![CDATA[Building an AI Video Subtitle Generator with Whisper]]></title><description><![CDATA[Whisper is an AI model from OpenAI that can be used to generate subtitles from audio or video files. Please click here to learn more.
In this blog, we'll use Docker to simplify the process. First, we'll place our audio or video files into a Docker co...]]></description><link>https://blog.hemant.lol/whisper</link><guid isPermaLink="true">https://blog.hemant.lol/whisper</guid><category><![CDATA[Open Source]]></category><category><![CDATA[AI]]></category><category><![CDATA[#ai-tools]]></category><category><![CDATA[subtitle generator]]></category><category><![CDATA[openai]]></category><dc:creator><![CDATA[Hemant]]></dc:creator><pubDate>Tue, 05 Sep 2023 14:13:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693921870923/c6df8c30-8cbe-457c-b613-7bbf1b7e7969.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Whisper is an AI model from OpenAI that can be used to generate subtitles from audio or video files. Please <a target="_blank" href="https://github.com/openai/whisper"><em>click here</em></a> to learn more.</p>
<p>In this blog, we'll use <strong>Docker</strong> to simplify the process. First, we'll place our audio or video files into a Docker container running an <strong>Ubuntu</strong> system. Then, we'll install <strong>Whisper</strong> and use it to generate our transcription files like <code>.srt</code>, <code>.vtt</code> etc. for our subtitles. And then using volume mapping we can also access the generated files in our local system.</p>
<ol>
<li><p>Let's begin by opening an empty project in VSCode.</p>
</li>
<li><p>Create a file named "Dockerfile" and copy the below Dockerfile content in it.</p>
<pre><code class="lang-dockerfile"> <span class="hljs-keyword">FROM</span> ubuntu

 <span class="hljs-keyword">RUN</span><span class="bash"> apt update &amp;&amp; apt install ffmpeg -y &amp;&amp; apt install python3 -y &amp;&amp; apt install python3-pip -y</span>

 <span class="hljs-keyword">RUN</span><span class="bash"> pip install -U openai-whisper</span>
 <span class="hljs-keyword">RUN</span><span class="bash"> pip install setuptools-rust</span>

 <span class="hljs-keyword">ENTRYPOINT</span><span class="bash"> [ <span class="hljs-string">"bash"</span> ]</span>
</code></pre>
<p> Now we'll build our docker image from this file but make sure that your <strong>docker daemon</strong> is running.</p>
</li>
<li><p>After that go ahead and run the following command:</p>
<pre><code class="lang-bash"> docker build -t my-whisper .
</code></pre>
<p> This might take a while because we're getting the <strong>Ubuntu</strong> image and setting up other things. Just hang tight and wait for it to finish!</p>
<p> Now get a sample video whose subtitle you want to generate. Then create a folder in the Desktop named "<strong>sample</strong>" and place your video in this folder.</p>
</li>
</ol>
<ol>
<li><p>Now copy the path of the video file and run the below command:</p>
<pre><code class="lang-bash"> docker run -it -v &lt;your sample folder path here&gt;:/home/videos my-whisper
</code></pre>
<p> After running this command, you will be in your container's bash. If you navigate to the <code>/home/vidoes</code> directory, you can access the sample video in your container.</p>
<p> Now inside <code>/home/videos</code> run the below command to generate the English subtitle of Hindi video.</p>
<pre><code class="lang-bash"> whisper sample.mp4 --language Hindi --task translate
</code></pre>
<p> After hitting enter, generating subtitles may take some time as AI models require a GPU to operate quickly. Since I am running it on a CPU, it will take longer but if you have GPU then it is going to be fast.</p>
<p> As this command finishes generating subtitles you do <code>ls</code> and check there are some transcription files in your container and as well as in your Desktop sample folder.</p>
<p> You can also test these subtitles by applying them on your video using tools like <strong>veed.io</strong></p>
</li>
</ol>
<p>So yayy!!. That's all in this blog and we have successfully generated our subtitles using <strong>Whisper</strong> AI model.</p>
<p>This blog is inspired by <a class="user-mention" href="https://hashnode.com/@piyushgarg">Piyush Garg</a>'s <a target="_blank" href="https://www.youtube.com/watch?v=AIAk8sN5zXE&amp;t"><em>video</em></a> <em>go and check it out also.</em></p>
<p>If you liked this blog please give it a thumbs-up!! 👍🏼</p>
]]></content:encoded></item><item><title><![CDATA[Connect Your Localhost to the Internet via Cloudflare Tunnel]]></title><description><![CDATA[If you're using an old computer at home to run a server for things like media, files, or websites, you might want to make it accessible on the internet. You can do this by the port forwarding option in your router's settings, However, it's not safe o...]]></description><link>https://blog.hemant.lol/cloudflare</link><guid isPermaLink="true">https://blog.hemant.lol/cloudflare</guid><category><![CDATA[cloudflare]]></category><category><![CDATA[localhost]]></category><category><![CDATA[tunneling]]></category><category><![CDATA[cloudflared]]></category><category><![CDATA[internet]]></category><dc:creator><![CDATA[Hemant]]></dc:creator><pubDate>Wed, 30 Aug 2023 08:06:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693382693239/5eea7f13-f10d-4a78-af5c-ed61383b2dd5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you're using an old computer at home to run a server for things like media, files, or websites, you might want to make it accessible on the internet. You can do this by the port forwarding option in your router's settings, However, it's not safe or advised to use this approach for serious or important use.</p>
<p>In this blog, I'll tell you a better way to make your local servers available online with strong security. We'll use a free service called Cloudflare Tunnel to connect to the internet securely with HTTPS, and you won't have to reveal your public IP address.</p>
<h2 id="heading-what-is-cloudflare-tunnel"><strong>What is Cloudflare Tunnel?</strong></h2>
<p>It's a tool that helps you securely share your stuff, like local servers, online. You don't need a public IP address or tricky router setups. When you use Cloudflare Tunnel on your computer (Windows, macOS, or Linux), it installs a lightweight helper (<strong>cloudflared</strong>). This helper links your local server with Cloudflare's network. With this, you can share things like websites, remote desktops, or other computer things safely on the internet.</p>
<p>This guide shows how to set up this helper on Windows, macOS, and Linux, and how you can make your local stuff available online in a safe way.</p>
<p>You can get a brief idea of how the Cloudflare tunnel enables access from your localhost to the internet by referring to the diagram below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693381548561/66c2ad9f-1e9c-41a2-8250-cb2f576e49c0.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-1-to-use-cloudflare-tunnel">1. To use Cloudflare Tunnel</h2>
<p>Firstly, We have to Install the <strong>cloudflared</strong> daemon on your system:</p>
<h3 id="heading-macos"><strong>MacOS</strong></h3>
<p>You can install <strong>cloudflared</strong> on macOS using Homebrew:</p>
<pre><code class="lang-bash">  brew install cloudflare/cloudflare/cloudflared
</code></pre>
<p>Alternatively, you can download the latest Darwin amd64 release directly from the <a target="_blank" href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/"><strong>downloads page</strong></a>.</p>
<h3 id="heading-linux"><strong>Linux</strong></h3>
<p>On Linux, you have two options:</p>
<ol>
<li><p>Install the .deb package using <code>dpkg</code>:</p>
<pre><code class="lang-bash"> wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb  
 sudo dpkg -i cloudflared-linux-amd64.deb
</code></pre>
</li>
<li><p>Install the .rpm package using <code>rpm</code>:</p>
<pre><code class="lang-bash"> wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-x86_64.rpm
 sudo rpm -i cloudflared-linux-x86_64.rpm
</code></pre>
</li>
</ol>
<h3 id="heading-windows"><strong>Windows</strong></h3>
<p>On Windows, you can download the appropriate <strong>.exe</strong> file from the <a target="_blank" href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/"><strong>downloads page</strong></a> and run it to install cloudflared.</p>
<p>After installation, you'll need to run <code>cloudflared.exe</code> as an administrator to start a tunnel.<br />OR<br />You can install <strong>cloudflared</strong> on windows using <strong>winget</strong>:</p>
<pre><code class="lang-bash">winget install --id Cloudflare.cloudflared
</code></pre>
<p>Now Confirm that <code>cloudflared</code> is installed correctly by running <code>cloudflared --version</code> in your command line:</p>
<pre><code class="lang-bash">$ cloudflared --version
cloudflared version 2023.8.0 (built 2023-08-23-1232 UTC)
</code></pre>
<h3 id="heading-2-initiate-a-cloudflare-tunnel">2. Initiate a Cloudflare Tunnel</h3>
<p>Once your local development server is up and running, you can start a new Cloudflare Tunnel by executing the command <code>cloudflared tunnel</code> in a fresh command line window. Include the <code>--url</code> flag followed by your localhost URL and port as parameters. As you run this command, <strong>cloudflared</strong> will display logs in your command line interface, and you'll see a banner featuring the tunnel URL:</p>
<pre><code class="lang-bash">$ cloudflared tunnel --url http://localhost:3000
2023-08-29T14:08:20Z INF Thank you <span class="hljs-keyword">for</span> trying Cloudflare Tunnel. Doing so, without a Cloudflare account, is a quick way to experiment and try it out. However, be aware that these account-less Tunnels have no uptime guarantee. If you intend to use Tunnels <span class="hljs-keyword">in</span> production you should use a pre-created named tunnel by following: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps
2023-08-29T14:08:20Z INF Requesting new quick Tunnel on trycloudflare.com...
2023-08-29T14:08:23Z INF +--------------------------------------------------------------------------------------------+
2023-08-29T14:08:23Z INF |  Your quick Tunnel has been created! Visit it at (it may take some time to be reachable):  |
2023-08-29T14:08:23Z INF |  https://finder-puppy-situated-eternal.trycloudflare.com                                   |
2023-08-29T14:08:23Z INF +--------------------------------------------------------------------------------------------+
2023-08-29T14:08:23Z INF Cannot determine default configuration path. No file [config.yml config.yaml] <span class="hljs-keyword">in</span> [~/.cloudflared ~/.cloudflare-warp ~/cloudflare-warp]
2023-08-29T14:08:23Z INF Version 2023.8.0
2023-08-29T14:08:23Z INF GOOS: windows, GOVersion: go1.20.6, GoArch: amd64
2023-08-29T14:08:23Z INF Settings: map[ha-connections:1 protocol:quic url:http://localhost:3000]
2023-08-29T14:08:23Z INF cloudflared will not automatically update on Windows systems.
2023-08-29T14:08:23Z INF Generated Connector ID: 8fa4e768-d32f-454b-b286-6cf6a38ac18b
2023-08-29T14:08:23Z INF Initial protocol quic
2023-08-29T14:08:23Z INF ICMP proxy will use 192.168.0.101 as <span class="hljs-built_in">source</span> <span class="hljs-keyword">for</span> IPv4
2023-08-29T14:08:23Z INF ICMP proxy will use fe80::bc0a:cd6a:780c:836a <span class="hljs-keyword">in</span> zone Wi-Fi as <span class="hljs-built_in">source</span> <span class="hljs-keyword">for</span> IPv6
2023-08-29T14:08:23Z INF cloudflared does not support loading the system root certificate pool on Windows. Please use --origin-ca-pool &lt;PATH&gt; to specify the path to the certificate pool
2023-08-29T14:08:23Z INF Starting metrics server on 127.0.0.1:64529/metrics
</code></pre>
<p>In this example, the randomly-generated URL <code>https://finder-puppy-situated-eternal.trycloudflare.com</code> has been created and assigned to your tunnel instance. Visiting this URL in a browser will show the application running, with requests being securely forwarded through Cloudflare’s global network, through the tunnel running on your machine, to <code>localhost:3000</code>:</p>
<p>But remember, the URL you get is like a temporary ticket. When you turn off your local server, the URL stops working. The moment you use the <code>cloudflared tunnel --url http://localhost:3000</code> command again, a new URL shows up. So, it's like a short-lived URL, not something that lasts forever.</p>
<p>If you're interested in securing a URL that remains constant over time, you can check out the next steps.</p>
<h3 id="heading-3-setting-up-a-permanent-url">3. Setting up a permanent URL.</h3>
<p>First, Create a Cloudflare account and add your domain name. You'll need a registered domain name to proceed.</p>
<p>You can check out <a target="_blank" href="https://www.spaceship.com/">spaceship</a> for cheap domain names.</p>
<p>Now after you get the domain name, you can move forward to the Cloudflare<br />dashboard. Inside the <strong>Websites</strong> section, click on the button that says "<strong>Add a site.</strong>"</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693371815088/2fee268b-f60d-4557-880e-ed1d4326e6e3.png" alt class="image--center mx-auto" /></p>
<p>After that, input your domain name and press the continue button.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693371916648/d64fef1b-a20c-464b-a067-fc27f342abc9.png" alt class="image--center mx-auto" /></p>
<p>Then, choose the Free Plan and click continue.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693372082219/7ee829c6-74ae-45df-baae-6f903ec31c21.png" alt class="image--center mx-auto" /></p>
<p>Next, you'll need to finish setting up your cloudflare's nameservers. You can follow these <a target="_blank" href="https://developers.cloudflare.com/automatic-platform-optimization/get-started/change-nameservers/">guides</a> to help you with the setup.</p>
<p>Once you've configured Cloudflare's nameservers, it could take up to 48 hours for your domain to become active. Don't worry if it takes a bit longer – usually, it's ready in 5-10 minutes, but sometimes it might take up to 48 hours.</p>
<p>Once your website's address is up and running, we can move forward with setting up our Cloudflare tunnel.</p>
<p>Next, select the Zero Trust option from the sidebar.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693375005225/a0d9f897-a876-40c7-a3a9-d4cd9c2f2788.png" alt class="image--center mx-auto" /></p>
<p>Then go to <strong>Access &gt; Tunnels</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693375091442/9eac59f1-a3a0-405c-a26c-6bbc9bbc0bf9.png" alt class="image--center mx-auto" /></p>
<p>Then, you'll find a button that says "<strong>Create a tunnel</strong>" Just click on it.</p>
<p>and then provide a name for your tunnel.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693375302938/32bea712-45c1-4821-9a64-271198cf86b2.png" alt class="image--center mx-auto" /></p>
<p>Next, you'll be shown instructions for installing the connector based on your setup. Once the connector is successfully installed, you'll notice it appearing in the lower connector box, replacing the previous message "No connectors installed".</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693377145327/4113a981-18c2-434d-be13-5b97fa9781e0.png" alt class="image--center mx-auto" /></p>
<p>Lastly, for the final step, you need to include <strong>public hostnames</strong> for your tunnel, just like what you see in the image below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693377205950/41901d1b-b800-45f8-9a48-3a5142817da4.png" alt class="image--center mx-auto" /></p>
<p>After you've entered all the necessary information, simply click on "<strong>Save Tunnel</strong>" in the lower right corner.</p>
<p>Then you'll see your tunnels in the <strong>Tunnels</strong> section</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693377411168/55b039d2-fcdb-449d-9c77-bfdea177c234.png" alt class="image--center mx-auto" /></p>
<p>Now if you open your domain name in a web browser, you'll find your local development site working there. You can even test by making code changes to see the updates on your domain. Just remember, your local development server should be running for this to work.</p>
<p>You can also include several routes in the <strong>public hostnames</strong>. Just click on your tunnel's name, select "<strong>configure</strong>," and go to the "<strong>public hostnames</strong>" section. From there, you can set up multiple routes, just like you see in the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1693377924389/26809e35-846d-4737-9b17-ce52fa155bd5.png" alt class="image--center mx-auto" /></p>
<p>Great! We've done it – we've managed to make our local website accessible on the internet. This means we can send this domain name to anyone, and they can see the changes we make in real-time. It's quite awesome!</p>
<p><img src="https://media.tenor.com/xUG50Jtht7QAAAAC/minions-yay.gif" alt class="image--center mx-auto" /></p>
<p>Feel free to take a look at <a class="user-mention" href="https://hashnode.com/@piyushgarg">Piyush Garg</a>'s <a target="_blank" href="https://www.youtube.com/watch?v=BnWfbv7Fy-k&amp;t=1136s"><strong>video</strong></a> on <em>how to expose your localhost to the internet</em>. This blog essentially presents the content of that video in written form.</p>
<p>If you enjoyed reading this blog, I'd appreciate a thumbs up from you. Your support keeps me motivated to bring you more informative content. Thank you for being a part of this journey!</p>
]]></content:encoded></item><item><title><![CDATA[Docker Networking Simplified:  A Beginner's Guide to Docker Networks]]></title><description><![CDATA[Docker networking allows containers to communicate with each other and the outside world. Several network types are supported to facilitate common use cases.
Docker Network Types
Docker has 5 built-in network drivers:

bridge : Default network. Isola...]]></description><link>https://blog.hemant.lol/docker</link><guid isPermaLink="true">https://blog.hemant.lol/docker</guid><category><![CDATA[Docker]]></category><category><![CDATA[Docker compose]]></category><category><![CDATA[Dockerfile]]></category><category><![CDATA[docker-network]]></category><category><![CDATA[docker images]]></category><dc:creator><![CDATA[Hemant]]></dc:creator><pubDate>Thu, 24 Aug 2023 18:12:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1692897189142/6370c145-ae77-4b47-997b-3d5ab4ccf72b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Docker networking allows containers to communicate with each other and the outside world. Several network types are supported to facilitate common use cases.</p>
<h1 id="heading-docker-network-types">Docker Network Types</h1>
<p>Docker has 5 built-in network drivers:</p>
<ul>
<li><p><code>bridge</code> : Default network. Isolates containers but allows them to communicate.</p>
</li>
<li><p><code>host</code>: Removes isolation and attaches the container directly to the host network.</p>
</li>
<li><p><code>overlay</code>: Allows containers on different Docker hosts to communicate.</p>
</li>
<li><p><code>macvlan</code>: Assigns each container a MAC address, exposing it as a physical network interface.</p>
</li>
<li><p><code>none</code>: Disables all networking for the container.</p>
</li>
</ul>
<p>Bridge networks are the most commonly used. Host networks are useful when binding ports directly to the host. Overlay networks span multiple Docker hosts.</p>
<h2 id="heading-basic-network-commands"><strong>Basic Network Commands</strong></h2>
<p>The <code>docker network</code> command allows you to create and manage Docker networks. The most commonly used subcommands are <code>create</code>, <code>ls</code>, <code>inspect</code>, <code>rm</code>, <code>connect</code> and <code>disconnect</code>.</p>
<ul>
<li><h3 id="heading-docker-network-create"><strong>docker network create</strong></h3>
</li>
</ul>
<p>Creates a Docker network. You can specify the network driver and options:</p>
<pre><code class="lang-css">  <span class="hljs-selector-tag">docker</span> <span class="hljs-selector-tag">network</span> <span class="hljs-selector-tag">create</span> <span class="hljs-selector-tag">--driver</span> <span class="hljs-selector-tag">bridge</span> <span class="hljs-selector-tag">my-network</span>
  <span class="hljs-selector-tag">docker</span> <span class="hljs-selector-tag">network</span> <span class="hljs-selector-tag">create</span> <span class="hljs-selector-tag">--driver</span> <span class="hljs-selector-tag">overlay</span> <span class="hljs-selector-tag">--subnet</span> 10<span class="hljs-selector-class">.0</span><span class="hljs-selector-class">.9</span><span class="hljs-selector-class">.0</span>/24 <span class="hljs-selector-tag">my-overlay</span>
</code></pre>
<ul>
<li><h3 id="heading-docker-network-ls"><strong>docker network ls</strong></h3>
</li>
</ul>
<p>Lists all networks:</p>
<pre><code class="lang-css">  <span class="hljs-selector-tag">docker</span> <span class="hljs-selector-tag">network</span> <span class="hljs-selector-tag">ls</span>
</code></pre>
<pre><code class="lang-bash">$ docker network ls
NETWORK ID     NAME           DRIVER    SCOPE
338357be06bf   bridge         bridge    <span class="hljs-built_in">local</span>
ee5e48ae4cbc   my-network     bridge    <span class="hljs-built_in">local</span>
bfd8a38e6635   host           host      <span class="hljs-built_in">local</span>
0cc57ea63f2a   none           null      <span class="hljs-built_in">local</span>
</code></pre>
<ul>
<li><h3 id="heading-docker-network-inspect"><strong>docker network inspect</strong></h3>
</li>
</ul>
<p>Inspects a network's details:</p>
<pre><code class="lang-css">  <span class="hljs-selector-tag">docker</span> <span class="hljs-selector-tag">network</span> <span class="hljs-selector-tag">inspect</span> <span class="hljs-selector-tag">bridge</span>
</code></pre>
<pre><code class="lang-bash">$  docker network inspect bridge
[
    {
        <span class="hljs-string">"Name"</span>: <span class="hljs-string">"bridge"</span>,
        <span class="hljs-string">"Id"</span>: <span class="hljs-string">"338357be06bf26c708d16e17417ce40f18e61db47d24df3ebfd0259f3961c490"</span>,
        <span class="hljs-string">"Created"</span>: <span class="hljs-string">"2023-08-24T17:38:23.1225357Z"</span>,
        <span class="hljs-string">"Scope"</span>: <span class="hljs-string">"local"</span>,
        <span class="hljs-string">"Driver"</span>: <span class="hljs-string">"bridge"</span>,
        <span class="hljs-string">"EnableIPv6"</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-string">"IPAM"</span>: {
            <span class="hljs-string">"Driver"</span>: <span class="hljs-string">"default"</span>,
            <span class="hljs-string">"Options"</span>: null,
            <span class="hljs-string">"Config"</span>: [
                {
                    <span class="hljs-string">"Subnet"</span>: <span class="hljs-string">"172.17.0.0/16"</span>,
                    <span class="hljs-string">"Gateway"</span>: <span class="hljs-string">"172.17.0.1"</span>
                }
            ]
        },
        <span class="hljs-string">"Internal"</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-string">"Attachable"</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-string">"Ingress"</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-string">"ConfigFrom"</span>: {
            <span class="hljs-string">"Network"</span>: <span class="hljs-string">""</span>
        },
        <span class="hljs-string">"ConfigOnly"</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-string">"Containers"</span>: {},
        <span class="hljs-string">"Options"</span>: {
            <span class="hljs-string">"com.docker.network.bridge.default_bridge"</span>: <span class="hljs-string">"true"</span>,
            <span class="hljs-string">"com.docker.network.bridge.enable_icc"</span>: <span class="hljs-string">"true"</span>,
            <span class="hljs-string">"com.docker.network.bridge.enable_ip_masquerade"</span>: <span class="hljs-string">"true"</span>,
            <span class="hljs-string">"com.docker.network.bridge.host_binding_ipv4"</span>: <span class="hljs-string">"0.0.0.0"</span>,
            <span class="hljs-string">"com.docker.network.bridge.name"</span>: <span class="hljs-string">"docker0"</span>,
            <span class="hljs-string">"com.docker.network.driver.mtu"</span>: <span class="hljs-string">"1500"</span>
        },
        <span class="hljs-string">"Labels"</span>: {}
    }
]
</code></pre>
<ul>
<li><h3 id="heading-docker-network-rm"><strong>docker network rm</strong></h3>
</li>
</ul>
<p>Removes a network:</p>
<pre><code class="lang-css">  <span class="hljs-selector-tag">docker</span> <span class="hljs-selector-tag">network</span> <span class="hljs-selector-tag">rm</span> <span class="hljs-selector-tag">my-network</span>
</code></pre>
<ul>
<li><h3 id="heading-docker-network-connect"><strong>docker network connect</strong></h3>
</li>
</ul>
<p>Connects a container to a network:</p>
<pre><code class="lang-bash">  docker network connect bridge container1
</code></pre>
<p>You can specify the IP address and aliases:</p>
<pre><code class="lang-css">  <span class="hljs-selector-tag">docker</span> <span class="hljs-selector-tag">network</span> <span class="hljs-selector-tag">connect</span> <span class="hljs-selector-tag">--ip</span> 172<span class="hljs-selector-class">.16</span><span class="hljs-selector-class">.238</span><span class="hljs-selector-class">.10</span> <span class="hljs-selector-tag">--alias</span> <span class="hljs-selector-tag">db</span> <span class="hljs-selector-tag">bridge</span> <span class="hljs-selector-tag">container1</span>
</code></pre>
<ul>
<li><h3 id="heading-docker-network-disconnect"><strong>docker network disconnect</strong></h3>
</li>
</ul>
<p>Disconnects a container from a network:</p>
<pre><code class="lang-css">  <span class="hljs-selector-tag">docker</span> <span class="hljs-selector-tag">network</span> <span class="hljs-selector-tag">disconnect</span> <span class="hljs-selector-tag">bridge</span> <span class="hljs-selector-tag">container1</span>
</code></pre>
<ul>
<li><h3 id="heading-docker-network-prune"><strong>docker network prune</strong></h3>
</li>
</ul>
<p>Removes all unused networks:</p>
<pre><code class="lang-css">  <span class="hljs-selector-tag">docker</span> <span class="hljs-selector-tag">network</span> <span class="hljs-selector-tag">prune</span>
</code></pre>
<h2 id="heading-docker-compose-networking">Docker Compose Networking</h2>
<p>Docker Compose makes it easy to manage networking between containers in an application. By default, Compose sets up a single network for your app and joins all containers to it. Containers can then communicate using the service names as hostnames.</p>
<p>However, Compose also allows you to define custom networks with specific options. This gives you more flexibility and control over how your containers are connected.</p>
<h3 id="heading-how-default-networking-works"><strong>How default networking works</strong></h3>
<p>By default, when you run <code>docker compose up</code>, Compose performs the following:</p>
<ul>
<li><p>A network called <code>[projectname]_default</code> is created.</p>
</li>
<li><p>Containers are created for each service defined in the <code>docker-compose.yml</code> file.</p>
</li>
<li><p>The containers join the default network and can be reached using their service names as hostnames.</p>
</li>
</ul>
<p>For example:</p>
<pre><code class="lang-yaml">  <span class="hljs-attr">services:</span>
    <span class="hljs-attr">web:</span> 
      <span class="hljs-attr">build:</span> <span class="hljs-string">.</span>
    <span class="hljs-attr">db:</span>
      <span class="hljs-attr">image:</span> <span class="hljs-string">postgres</span>
</code></pre>
<p>The <code>web</code> container can then connect to the <code>db</code> container using the hostname <code>db</code>.</p>
<h3 id="heading-specifying-custom-networks"><strong>Specifying custom networks</strong></h3>
<p>You can define custom networks in the <code>networks</code> section of your Compose file:</p>
<pre><code class="lang-yaml">  <span class="hljs-attr">networks:</span>
    <span class="hljs-attr">front-tier:</span>
    <span class="hljs-attr">back-tier:</span>
</code></pre>
<p>Then, you can attach services to the networks:</p>
<pre><code class="lang-yaml">  <span class="hljs-attr">services:</span>
    <span class="hljs-attr">web:</span>
      <span class="hljs-attr">networks:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">front-tier</span>
    <span class="hljs-attr">db:</span>  
      <span class="hljs-attr">networks:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">back-tier</span>
</code></pre>
<p>This isolates the <code>web</code> and <code>db</code> containers on separate networks. Only services attached to both networks can communicate.</p>
<p>You can also:</p>
<ul>
<li><p>Specify static IPs for containers</p>
</li>
<li><p>Connect to external networks</p>
</li>
<li><p>Use custom network drivers</p>
</li>
<li><p>Configure the default network</p>
</li>
</ul>
<h3 id="heading-docker-compose-networking-example"><strong>Docker Compose networking example</strong></h3>
<p>Here's an example <code>docker-compose.yml</code> file that defines two custom networks:</p>
<pre><code class="lang-yaml">  <span class="hljs-attr">networks:</span>
    <span class="hljs-attr">backnet:</span>  
    <span class="hljs-attr">frontnet:</span>

  <span class="hljs-attr">services:</span>  
    <span class="hljs-attr">db:</span>  
      <span class="hljs-attr">networks:</span>  
        <span class="hljs-bullet">-</span> <span class="hljs-string">backnet</span>  
    <span class="hljs-attr">backend:</span>
      <span class="hljs-attr">networks:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">backnet</span>  
        <span class="hljs-bullet">-</span> <span class="hljs-string">frontnet</span> 
    <span class="hljs-attr">proxy:</span>
      <span class="hljs-attr">networks:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">frontnet</span>
</code></pre>
<p>The <code>db</code> service is only connected to the <code>backnet</code> while the <code>backend</code> service is connected to both <code>backnet</code> and <code>frontnet</code>. This allows the <code>backend</code> service to communicate with both <code>db</code> and <code>proxy</code> while isolating <code>db</code> and <code>proxy</code>.</p>
<h3 id="heading-benefits-of-docker-compose-networking"><strong>Benefits of Docker Compose networking</strong></h3>
<p>Docker Compose makes it easy to manage networking between containers in an application:</p>
<ul>
<li><p>Containers can communicate using service names by default</p>
</li>
<li><p>You can isolate services on custom networks</p>
</li>
<li><p>Compose manages port mappings between containers and the host</p>
</li>
<li><p>Advanced options allow for more complex network topologies</p>
</li>
</ul>
<p>Overall, Compose networking drastically simplifies the process of connecting containers and allows you to focus on your application logic.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Docker networking provides flexibility in how containers communicate and connect to external networks. The appropriate network type depends on your use case. Bridge networks cover the majority of scenarios, with host and overlay networks fulfilling more specialized roles.</p>
<p>Hope this blog helped you somehow! Let me know if you have any other questions.</p>
]]></content:encoded></item><item><title><![CDATA[Mastering CSS Grid: Creating Complex Layouts Made Easy]]></title><description><![CDATA[Are you ready to dive into the world of CSS Grid? Get ready to transform your layout skills from basic to extraordinary! In this comprehensive guide, we'll take you through the ins and outs of CSS Grid – from the fundamentals to creating intricate la...]]></description><link>https://blog.hemant.lol/grid</link><guid isPermaLink="true">https://blog.hemant.lol/grid</guid><category><![CDATA[grid]]></category><category><![CDATA[CSS]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[HTML]]></category><category><![CDATA[Responsive Web Design]]></category><dc:creator><![CDATA[Hemant]]></dc:creator><pubDate>Mon, 21 Aug 2023 16:17:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1692633643983/476b0316-605b-4860-87a4-5e69b6cb2da8.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are you ready to dive into the world of CSS Grid? Get ready to transform your layout skills from basic to extraordinary! In this comprehensive guide, we'll take you through the ins and outs of CSS Grid – from the fundamentals to creating intricate layouts. You'll learn about its advantages, essential properties, and powerful functions, all while building a strong foundation for designing stunning and responsive web layouts. Let's get started with simple explanations, step-by-step instructions, interactive demos, and code examples to ensure you grasp the concepts effortlessly.</p>
<h2 id="heading-understanding-css-grid-system-and-its-advantages"><strong>Understanding CSS Grid System and Its Advantages</strong></h2>
<p>CSS Grid is like a master puzzle solver for creating layouts. It's a system that allows you to organize content in rows and columns, opening up a world of possibilities.</p>
<h3 id="heading-advantages-of-css-grid"><strong>Advantages of CSS Grid</strong></h3>
<ol>
<li><p><strong>Layout Mastery</strong>: CSS Grid simplifies complex layouts. It's like having a blueprint that guides you in placing items on your web page.</p>
</li>
<li><p><strong>Responsive Magic</strong>: Creating designs that adapt to different screen sizes becomes seamless with CSS Grid. It automatically adjusts your layout, making it look great on various devices.</p>
</li>
<li><p><strong>Precision Spacing</strong>: Say goodbye to messy spacing. CSS Grid gives you control over the gaps between columns and rows, resulting in a clean and organized layout.</p>
</li>
<li><p><strong>Centering Made Simple</strong>: Centering elements vertically and horizontally used to be tricky. CSS Grid makes it a breeze with straightforward alignment settings.</p>
</li>
<li><p><strong>Accessibility Boost</strong>: By using semantic HTML in combination with CSS Grid, you're ensuring that your layout is accessible to everyone, including those who rely on screen readers.</p>
</li>
</ol>
<h2 id="heading-exploring-essential-properties-and-functions"><strong>Exploring Essential Properties and Functions</strong></h2>
<h3 id="heading-properties"><strong>Properties:</strong></h3>
<ul>
<li><p><strong>display</strong>: Transforms an element into a grid container: <code>display: grid;</code>.</p>
</li>
<li><p><strong>grid-template-columns</strong> and <strong>grid-template-rows</strong>: Defines the columns and rows in your grid layout.</p>
</li>
<li><p><strong>grid-template-areas</strong>: Creates named grid areas for easy placement of items.</p>
</li>
<li><p><strong>grid-template</strong>: A shorthand for specifying columns, rows, and areas in a single line.</p>
</li>
<li><p><strong>grid-auto-columns</strong> and <strong>grid-auto-rows</strong>: Sets the size of columns and rows not defined in the grid layout.</p>
</li>
<li><p><strong>grid-auto-flow</strong>: Controls the placement of items added to the grid.</p>
</li>
<li><p><strong>grid</strong>, <strong>grid-row-start</strong>, <strong>grid-column-start</strong>, <strong>grid-row-end</strong>, <strong>grid-column-end</strong>: These properties allow you to place items in specific grid areas.</p>
</li>
<li><p><strong>grid-row</strong>, <strong>grid-column</strong>: A shorthand for specifying the starting and ending positions of items.</p>
</li>
<li><p><strong>grid-area</strong>: Combines grid-row and grid-column to place items in named areas.</p>
</li>
<li><p><strong>row-gap</strong> and <strong>column-gap</strong>: Define spacing between rows and columns.</p>
</li>
<li><p><strong>gap</strong>: A shorthand for setting both row and column gaps.</p>
</li>
</ul>
<h3 id="heading-functions"><strong>Functions:</strong></h3>
<ul>
<li><p><strong>repeat()</strong>: Repeats a pattern a certain number of times: <code>repeat(3, 1fr);</code> creates three equal columns.</p>
</li>
<li><p><strong>minmax()</strong>: Sets a size range for columns or rows: <code>minmax(100px, 1fr);</code> ensures a minimum width of 100px and maximum flexibility.</p>
</li>
<li><p><strong>fit-content()</strong>: Sizes a column or row based on its content, but not exceeding a specified value: <code>fit-content(200px);</code> keeps the size within 200px.  </p>
</li>
</ul>
<h2 id="heading-creating-layouts-with-css-grid"><strong>Creating Layouts with CSS Grid</strong></h2>
<p>Now let's put theory into practice with some layout examples:</p>
<h3 id="heading-example-1-basic-grid-layout"><strong>Example 1: Basic Grid Layout</strong></h3>
<p>Imagine creating a simple 2x2 grid.</p>
<ol>
<li><strong>HTML</strong>:</li>
</ol>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"grid-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>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>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>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> <span class="hljs-attr">class</span>=<span class="hljs-string">"item"</span>&gt;</span>4<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>
</code></pre>
<ol>
<li><strong>CSS</strong>:</li>
</ol>
<pre><code class="lang-css"><span class="hljs-selector-class">.grid-container</span> {
  <span class="hljs-attribute">display</span>: grid;
  <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-built_in">repeat</span>(<span class="hljs-number">2</span>, <span class="hljs-number">1</span>fr);
  <span class="hljs-attribute">grid-template-rows</span>: <span class="hljs-built_in">repeat</span>(<span class="hljs-number">2</span>, <span class="hljs-number">100px</span>);
  <span class="hljs-attribute">gap</span>: <span class="hljs-number">10px</span>;
}

<span class="hljs-selector-class">.item</span> {
  <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#ccc</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">text-align</span>: center;
}
</code></pre>
<p><strong>Output:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692633201980/4e8c9791-9c2c-496e-b3a1-883ae360c973.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-example-2-responsive-photo-gallery"><strong>Example 2: Responsive Photo Gallery</strong></h3>
<p>Create a responsive photo gallery that adapts to different screens.</p>
<ol>
<li><strong>HTML</strong>:</li>
</ol>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"photo-gallery"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Image 1"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Image 2"</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- Add more images here --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<ol>
<li><strong>CSS</strong>:</li>
</ol>
<pre><code class="lang-css"><span class="hljs-selector-class">.photo-gallery</span> {
  <span class="hljs-attribute">display</span>: grid;
  <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-built_in">repeat</span>(auto-fit, minmax(<span class="hljs-number">200px</span>, <span class="hljs-number">1</span>fr));
  <span class="hljs-attribute">gap</span>: <span class="hljs-number">10px</span>;
}

<span class="hljs-selector-class">.photo-gallery</span> <span class="hljs-selector-tag">img</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">height</span>: auto;
}
</code></pre>
<p><strong>Output:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692633435923/78b5d4d5-2eb1-4880-9cbc-e9c7678996e1.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>CSS Grid is a game-changer in the world of web layout design. Its flexibility, responsiveness, and ease of use empower developers to create stunning and intricate layouts that adapt seamlessly across various devices. By understanding the CSS Grid system and experimenting with different layout scenarios, you'll be well on your way to mastering this essential tool for modern web development.</p>
<p>Feel free to experiment with the provided code examples and modify them to suit your own projects. Happy gridding!</p>
<ul>
<li><a target="_blank" href="https://codepen.io/hemantwasthere/pen/XWoJVez"><strong><em>codepen</em></strong></a> link for the above examples</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[We can FINALLY animate gradients with CSS!]]></title><description><![CDATA[Gradients are commonly used in web design to create smooth color transitions and add visual appeal to elements. The ability to animate gradients using CSS variables can provide even more flexibility and dynamic effects. In this blog post, we will del...]]></description><link>https://blog.hemant.lol/moving-gradients</link><guid isPermaLink="true">https://blog.hemant.lol/moving-gradients</guid><category><![CDATA[CSS]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[Gradients]]></category><category><![CDATA[Animating Gradients]]></category><dc:creator><![CDATA[Hemant]]></dc:creator><pubDate>Sun, 18 Jun 2023 09:18:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1687070556605/bc51742c-d0b7-43ba-b0b9-561959401987.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Gradients are commonly used in web design to create smooth color transitions and add visual appeal to elements. The ability to animate gradients using CSS variables can provide even more flexibility and dynamic effects. In this blog post, we will delve into the concept of animating gradients with CSS variables and showcase some examples.</p>
<p>Gradients have long been a powerful tool in CSS for creating beautiful color transitions. However, until recently, animating gradients directly was a challenge. Enter the @property rule in CSS, which introduces the ability to define the type of CSS variables, including color variables. With this new capability, we can animate variables from one color to another and apply them to gradients. In this blog post, we will explore how to animate gradients using CSS variables and unlock a world of creative possibilities.</p>
<p>You can create a new Next.js project interactively by running the below command:</p>
<pre><code class="lang-bash">yarn create next-app
</code></pre>
<p>You will then be asked the following prompts:</p>
<pre><code class="lang-bash">What is your project named?  my-app
Would you like to use TypeScript with this project?  No / Yes
Would you like to use ESLint with this project?  No / Yes
Would you like to use Tailwind CSS with this project?  No / Yes
Would you like to use `src/` directory with this project?  No / Yes
Use App Router (recommended)?  No / Yes
Would you like to customize the default import <span class="hljs-built_in">alias</span>?  No / Yes
</code></pre>
<p>Just select options according to the below image.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1687077276667/e4cc5087-4a2b-4a31-9921-6ba71db88412.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-1-overwrite-your-globalcss-file-with-the-below-css">1. Overwrite your <code>global.css</code> file with the below CSS:</h3>
<pre><code class="lang-css"><span class="hljs-keyword">@tailwind</span> base;
<span class="hljs-keyword">@tailwind</span> components;
<span class="hljs-keyword">@tailwind</span> utilities;

<span class="hljs-keyword">@layer</span> base {
  <span class="hljs-keyword">@property</span> --color-a {
    <span class="hljs-selector-tag">syntax</span>: "&lt;<span class="hljs-selector-tag">color</span>&gt;";
    <span class="hljs-selector-tag">inherits</span>: <span class="hljs-selector-tag">true</span>;
    <span class="hljs-selector-tag">initial-value</span>: <span class="hljs-selector-tag">transparent</span>;
  }
  <span class="hljs-keyword">@property</span> --color-b {
    <span class="hljs-selector-tag">syntax</span>: "&lt;<span class="hljs-selector-tag">color</span>&gt;";
    <span class="hljs-selector-tag">inherits</span>: <span class="hljs-selector-tag">true</span>;
    <span class="hljs-selector-tag">initial-value</span>: <span class="hljs-selector-tag">transparent</span>;
  }
  <span class="hljs-keyword">@property</span> --color-c {
    <span class="hljs-selector-tag">syntax</span>: "&lt;<span class="hljs-selector-tag">color</span>&gt;";
    <span class="hljs-selector-tag">inherits</span>: <span class="hljs-selector-tag">true</span>;
    <span class="hljs-selector-tag">initial-value</span>: <span class="hljs-selector-tag">transparent</span>;
  }
}

<span class="hljs-keyword">@layer</span> components {
  <span class="hljs-selector-class">.range</span> {
    <span class="hljs-attribute">appearance</span>: none;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
    <span class="hljs-attribute">background</span>: white;
    <span class="hljs-attribute">height</span>: <span class="hljs-number">2px</span>;
  }
  <span class="hljs-selector-class">.range</span><span class="hljs-selector-pseudo">::-webkit-slider-thumb</span> {
    <span class="hljs-attribute">appearance</span>: none;
    <span class="hljs-attribute">background</span>: <span class="hljs-built_in">var</span>(--color-b);
    <span class="hljs-attribute">border</span>: <span class="hljs-number">2px</span> solid white;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">36px</span>;
    <span class="hljs-attribute">height</span>: <span class="hljs-number">36px</span>;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">36px</span>;
    <span class="hljs-attribute">cursor</span>: pointer;
  }
  <span class="hljs-selector-class">.range</span><span class="hljs-selector-pseudo">::-moz-range-thumb</span> {
    <span class="hljs-attribute">appearance</span>: none;
    <span class="hljs-attribute">background</span>: <span class="hljs-built_in">var</span>(--color-b);
    <span class="hljs-attribute">border</span>: <span class="hljs-number">2px</span> solid white;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">36px</span>;
    <span class="hljs-attribute">height</span>: <span class="hljs-number">36px</span>;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">36px</span>;
    <span class="hljs-attribute">cursor</span>: pointer;
  }
}
</code></pre>
<p><a target="_blank" href="https://caniuse.com/mdn-css_at-rules_property"><strong>@property Browser Support:</strong></a></p>
<p><a target="_blank" href="https://caniuse.com/mdn-css_at-rules_property"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1687078059989/c4dfe7eb-4c66-4ee8-9400-13ea76bbedb0.png" alt class="image--center mx-auto" /></a></p>
<p><em>Read more about</em> <strong><em>@property</em></strong> - <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/@property">MDN Docs</a></p>
<h3 id="heading-2-then-add-the-below-in-your-tailwindconfigjs">2. Then Add the below in your <code>tailwind.config.js</code></h3>
<pre><code class="lang-javascript"><span class="hljs-comment">/** <span class="hljs-doctag">@type <span class="hljs-type">{import('tailwindcss').Config}</span> </span>*/</span>
<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">content</span>: [
    <span class="hljs-string">'./pages/**/*.{js,ts,jsx,tsx,mdx}'</span>,
    <span class="hljs-string">'./components/**/*.{js,ts,jsx,tsx,mdx}'</span>,
    <span class="hljs-string">'./app/**/*.{js,ts,jsx,tsx,mdx}'</span>,
  ],
  <span class="hljs-attr">theme</span>: {
    <span class="hljs-attr">extend</span>: {
      <span class="hljs-attr">backgroundImage</span>: {
        <span class="hljs-string">'gradient-radial'</span>: <span class="hljs-string">'radial-gradient(var(--tw-gradient-stops))'</span>,
        <span class="hljs-string">'gradient-conic'</span>:
          <span class="hljs-string">'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))'</span>,
      },
      <span class="hljs-attr">keyframes</span>: {
        <span class="hljs-attr">blob</span>: {
          <span class="hljs-string">"0%"</span>: {
            <span class="hljs-attr">translate</span>: <span class="hljs-string">"0 0"</span>,
            <span class="hljs-attr">rotate</span>: <span class="hljs-string">"0deg"</span>,
          },
          <span class="hljs-string">"30%"</span>: {
            <span class="hljs-attr">rotate</span>: <span class="hljs-string">"40deg"</span>,
          },
          <span class="hljs-string">"50%"</span>: {
            <span class="hljs-attr">transform</span>: <span class="hljs-string">"translate(300px, 390px) scale(1.1)"</span>,
          },
          <span class="hljs-string">"80%"</span>: {
            <span class="hljs-attr">rotate</span>: <span class="hljs-string">"90%"</span>,
          },
        },
      },
      <span class="hljs-attr">animation</span>: {
        <span class="hljs-attr">blob</span>: <span class="hljs-string">"blob 8s infinite cubic-bezier(0.6, -0.28, 0.735, 0.045)"</span>,
        <span class="hljs-string">"blob-reverse"</span>:
          <span class="hljs-string">"blob 10s infinite cubic-bezier(0.215, 0.61, 0.355, 1) reverse"</span>,
      },
    },
  },
  <span class="hljs-attr">plugins</span>: [],
}
</code></pre>
<h3 id="heading-3-we-have-all-our-css-and-animations-ready">3. We have all our CSS and Animations ready.</h3>
<p>Now go to <code>index.tsx</code> file and copy it below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { useEffect, useRef, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-built_in">enum</span> Feeling {
  Sad = <span class="hljs-number">1</span>,
  Neutral = <span class="hljs-number">2</span>,
  Happy = <span class="hljs-number">3</span>,
}

<span class="hljs-keyword">const</span> feelingColorMap = {
  [Feeling.Sad]: [<span class="hljs-string">"#394e7a"</span>, <span class="hljs-string">"    #8e9ac7"</span>, <span class="hljs-string">"#4ee"</span>],
  [Feeling.Neutral]: [<span class="hljs-string">"#22d"</span>, <span class="hljs-string">"#c8f8ff"</span>, <span class="hljs-string">"#6d2"</span>],
  [Feeling.Happy]: [<span class="hljs-string">"#39f"</span>, <span class="hljs-string">"#f4e54d"</span>, <span class="hljs-string">"#fa3"</span>],
};

<span class="hljs-keyword">const</span> feelingLabelMap = {
  [Feeling.Sad]: <span class="hljs-string">"Could be better"</span>,
  [Feeling.Neutral]: <span class="hljs-string">"Okay"</span>,
  [Feeling.Happy]: <span class="hljs-string">"Happy"</span>,
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> wrapperRef = useRef&lt;HTMLDivElement | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [feeling, setFeeling] = useState&lt;Feeling&gt;(Feeling.Neutral);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (!wrapperRef.current) <span class="hljs-keyword">return</span>;

    <span class="hljs-keyword">const</span> [a, b, c] = feelingColorMap[feeling];

    wrapperRef.current.style.setProperty(<span class="hljs-string">"--color-a"</span>, a);
    wrapperRef.current.style.setProperty(<span class="hljs-string">"--color-b"</span>, b);
    wrapperRef.current.style.setProperty(<span class="hljs-string">"--color-c"</span>, c);
  }, [feeling]);

  <span class="hljs-keyword">return</span> (
    &lt;main className=<span class="hljs-string">"flex min-h-[100dvh] w-full items-center justify-center"</span>&gt;
      &lt;div
        ref={wrapperRef}
        className=<span class="hljs-string">"relative mx-auto aspect-[9/16] w-[360px] max-w-full overflow-hidden rounded-2xl bg-gradient-to-br from-[--color-a] via-[--color-b] to-[--color-c] p-8 text-white duration-500 ease-in [transition-property:_--color-a,_--color-b,_--color-c] before:absolute before:left-[20%] before:top-[10%] before:h-[50%] before:w-[70%] before:origin-[60%] before:animate-blob before:rounded-3xl before:bg-gradient-to-br before:from-[--color-a] before:to-[--color-b] before:blur-[50px] before:brightness-125 after:absolute after:left-[40%] after:top-[30%] after:h-[80%] after:w-[70%] after:origin-[60%] after:animate-blob-reverse after:rounded-3xl after:bg-gradient-to-br after:from-[--color-a] after:to-[--color-b] after:blur-[50px] after:brightness-125"</span>
      &gt;
        &lt;div className=<span class="hljs-string">"relative z-10"</span>&gt;
          &lt;h1 className=<span class="hljs-string">"mb-12 text-5xl font-medium leading-tight"</span>&gt;
            How are you feeling today?
          &lt;/h1&gt;

          &lt;h2 className=<span class="hljs-string">"mb-4 text-center text-2xl font-medium"</span>&gt;
            {feelingLabelMap[feeling]}
          &lt;/h2&gt;

          &lt;input
            className=<span class="hljs-string">"range"</span>
            onChange={<span class="hljs-function">(<span class="hljs-params">ev</span>) =&gt;</span> setFeeling(ev.target.value <span class="hljs-keyword">as</span> unknown <span class="hljs-keyword">as</span> Feeling)}
            <span class="hljs-keyword">type</span>=<span class="hljs-string">"range"</span>
            min={<span class="hljs-number">1</span>}
            value={feeling}
            max={<span class="hljs-number">3</span>}
            step={<span class="hljs-number">1</span>}
          /&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/main&gt;
  );
}
</code></pre>
<h3 id="heading-and-voila-behold-the-mesmerizing-animation-of-our-gradient">And voila! Behold the mesmerizing animation of our gradient.</h3>
<p>Check out the resulting output here - <a target="_blank" href="https://moving-gradients.vercel.app/">https://moving-gradients.vercel.app/</a></p>
<p><a target="_blank" href="https://github.com/hemantwasthere/moving-gradients"><strong><em>source code</em></strong></a></p>
<p><a target="_blank" href="https://codesandbox.io/p/github/hemantwasthere/moving-gradients/main?file=/pages/index.tsx:12,35&amp;workspaceId=7dafc1f0-64ad-4415-9472-d0cf4fe2f5a4"><strong><em>codesandbox</em></strong></a></p>
<p>This design and example are inspired by <a target="_blank" href="https://dribbble.com/shots/20059351-Prototype-Survey"><strong><em>dribble</em></strong></a> and <a target="_blank" href="https://www.frontend.fyi/v/animated-gradients-with-css"><strong><em>frontend.fyi</em></strong></a> with ❤️</p>
]]></content:encoded></item><item><title><![CDATA[21 Fantastic Web Features You Haven't Explored]]></title><description><![CDATA[1. HTML <dialog> tag
The web is constantly evolving, with new HTML elements being introduced to enhance the user experience. One such addition is the <dialog> HTML tag, which provides a native way to create modal dialogs within web applications. In t...]]></description><link>https://blog.hemant.lol/21-fantastic-web-features-you-havent-explored</link><guid isPermaLink="true">https://blog.hemant.lol/21-fantastic-web-features-you-havent-explored</guid><category><![CDATA[Web Development]]></category><category><![CDATA[web]]></category><category><![CDATA[#newfeatures]]></category><category><![CDATA[features]]></category><dc:creator><![CDATA[Hemant]]></dc:creator><pubDate>Sun, 11 Jun 2023 10:35:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1686479367726/c2c616ec-d0d8-45e1-a468-b1fa09db5692.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-1-html-tag">1. HTML <code>&lt;dialog&gt;</code> tag</h1>
<p>The web is constantly evolving, with new HTML elements being introduced to enhance the user experience. One such addition is the <code>&lt;dialog&gt;</code> HTML tag, which provides a native way to create modal dialogs within web applications. In this blog post, we'll delve into the details of the <code>&lt;dialog&gt;</code> tag, understand its usage, explore some practical examples, and discuss the browser support it enjoys.</p>
<p>Understanding the <code>&lt;dialog&gt;</code> Tag: The <code>&lt;dialog&gt;</code> tag is an HTML5 element that represents a dialog box or a modal window within a web page. It allows developers to create interactive and contextual dialogs, such as alert boxes, confirmation dialogs, or custom pop-up windows, without relying on external libraries or frameworks.</p>
<p>Usage and Syntax: To utilize the <code>&lt;dialog&gt;</code> tag, you first need to define it within the HTML structure. Here's an example of the basic syntax:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dialog</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"dialog"</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Welcome to My Web App<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Thank you for visiting! Enjoy your stay.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dialog</span>&gt;</span>
</code></pre>
<p>In this example, we create a dialog with the <code>id</code> attribute set to "dialog" and include some content within the <code>&lt;dialog&gt;</code> tags.</p>
<p><strong>Opening and Closing the Dialog:</strong> To open the dialog, you can use showModal method of dialog by accessing it using its id. To close the dialog, you can call the <code>close()</code> method on the dialog element accessing it by its id. Here's an example:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dialog</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"dialog"</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Welcome to My Web App<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Thank you for visiting! Enjoy your stay.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"dialog.close()"</span>&gt;</span>Close<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dialog</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"dialog.showModal()"</span>&gt;</span>Open Dialog<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p><strong>Styling the Dialog:</strong> The appearance of the dialog box can be customized using CSS. By default, most modern browsers provide a simple and minimalistic design for the dialog box. However, you can override the default styles and apply your own to match the look and feel of your web application. We can also add animations to dialog element. Here is an example:</p>
<p><strong>HTML file:</strong></p>
<pre><code class="lang-xml"><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> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</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">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Exploring Dialog tag<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"style.css"</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">"wrapper"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">dialog</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"dialog"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"dialog"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Welcome to My Web App<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Thank you for visiting! Enjoy your stay.<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">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"dialog.close()"</span>&gt;</span>Close via btn<span class="hljs-tag">&lt;/<span class="hljs-name">button</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">form</span>=<span class="hljs-string">"dialog"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"dialog.close()"</span>&gt;</span>Close via form<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">dialog</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"dialog.showModal()"</span>&gt;</span>Open Dialog<span class="hljs-tag">&lt;/<span class="hljs-name">button</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><strong>CSS file</strong>:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100vh</span>;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100vw</span>;
  <span class="hljs-attribute">overflow</span>: hidden;
}

<span class="hljs-selector-tag">button</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#1b1c1d</span>;
  <span class="hljs-attribute">border</span>: none;
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">15px</span> <span class="hljs-number">32px</span>;
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">text-decoration</span>: none;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">16px</span>;
  <span class="hljs-attribute">cursor</span>: pointer;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">5px</span>;
  <span class="hljs-attribute">transition</span>: all <span class="hljs-number">0.2s</span> ease-in-out;
  <span class="hljs-attribute">z-index</span>: <span class="hljs-number">1</span>;
}

<span class="hljs-selector-class">.wrapper</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">flex-direction</span>: column;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">justify-content</span>: center;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100%</span>;
}

<span class="hljs-selector-tag">dialog</span><span class="hljs-selector-pseudo">::backdrop</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">27</span>, <span class="hljs-number">28</span>, <span class="hljs-number">29</span>, <span class="hljs-number">0.945</span>);
}
<span class="hljs-selector-tag">dialog</span> {
  <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">scale</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">display</span>: block;
  <span class="hljs-attribute">transition</span>: all <span class="hljs-number">0.2s</span> ease-in-out;
}
<span class="hljs-selector-tag">dialog</span><span class="hljs-selector-attr">[open]</span> {
  <span class="hljs-attribute">opacity</span>: <span class="hljs-number">1</span>;
  <span class="hljs-attribute">scale</span>: <span class="hljs-number">2</span>;
}
</code></pre>
<p><strong>OUTPUT:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686286761270/1a33033f-6a82-409e-9073-5beb5e8f8531.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686286715354/f614193a-2802-49a6-a0ca-e6659eaa6b63.png" alt class="image--center mx-auto" /></p>
<p><strong>Browser Support:</strong> The <code>&lt;dialog&gt;</code> tag enjoys decent support across modern web browsers. Here's a summary of its browser compatibility as of the time of writing:</p>
<p><a target="_blank" href="https://caniuse.com/dialog"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686286847517/e8decc0e-e9a9-4d56-bc02-d9b18ce2c333.png" alt class="image--center mx-auto" /></a></p>
<p>For older browsers that do not support the <code>&lt;dialog&gt;</code> tag, it will be treated as an unknown element and can be styled accordingly using CSS. Additionally, a JavaScript polyfill like "dialog-polyfill" can be used to provide a fallback implementation for unsupported browsers.</p>
<h1 id="heading-2-popover"><strong>2. Popover</strong></h1>
<p>Building popovers, such as menus, toggletips, and dialogs, in browsers can be a complex task. However, a new set of declarative HTML APIs is being introduced to simplify this process, starting with the popover attribute in Chromium 114. This attribute allows developers to harness the browser's capabilities for managing focus, open/close states, and keyboard bindings, making popover creation more straightforward and efficient. In this point, we will explore the features and usage of the popover attribute, its benefits, and clarify its differences from modal dialogs.</p>
<p>Simplifying Popover Creation with the Popover Attribute: The popover attribute is designed to streamline the creation of popovers in web applications. By leveraging this attribute, developers can offload the complexity of managing various aspects of popovers to the browser itself. Here are some key features and concepts associated with the popover attribute:<br />As of today, this feature is experimental so in order to use it you need to enable "Experimental Web Platform features" in your browser:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686313214954/51aa910f-1083-4704-aebb-78bdbc44121b.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p><strong>Basic Popover Structure:</strong> To create a basic popover, you need to add the popover attribute to the element containing the popover content. Additionally, you assign an ID to this element and use a popovertarget attribute with the value of the popover's ID on the element that triggers the popover.</p>
<pre><code class="lang-xml">  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">popovertarget</span>=<span class="hljs-string">"poppinoff"</span> <span class="hljs-attr">popover-trigger</span>=<span class="hljs-string">"hover"</span>&gt;</span>Open<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"poppinoff"</span> <span class="hljs-attr">popover</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>The feature be poppin'<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>
</code></pre>
</li>
<li><p><strong>Supported Functionality:</strong> The popover attribute supports several essential functionalities, including promotion to the top layer, light-dismiss functionality, default focus management, accessible keyboard bindings, and accessible component bindings. These features ensure that popovers are accessible and can be interacted with efficiently by users.</p>
</li>
<li><p><strong>Explicit and Implicit Popovers:</strong> By default, a popover with a popovertarget will toggle open and closed automatically. However, explicit popovers can be created using popovertargetaction. This allows developers to have more control over popover behavior and tailor it to specific requirements. Manual popovers do not force close any other element type and do not close via light-dismiss.</p>
</li>
<li><p><strong>CSS Anchoring:</strong> The popover attribute can be combined with CSS anchoring techniques to ensure that the popover is always anchored to its toggle trigger. This provides a consistent and visually pleasing experience for users.</p>
</li>
</ul>
<p>Popover Attribute vs. Modal Dialogs: While the popover attribute can be used to create modal dialog-like experiences, it's important to note that there are key differences between the two. Modal dialogs typically have a higher level of interaction and restrict user input to the dialog itself until it is closed. Popovers, on the other hand, allow users to interact with other elements on the page while the popover remains open.</p>
<p>Benefits and Future Capabilities: The introduction of the popover attribute is part of a broader effort to enhance web application development by providing declarative APIs. These APIs aim to simplify complexity, improve accessibility, and make building web applications more manageable. The popover attribute is just the beginning, and more capabilities are expected to be added in the future.</p>
<h1 id="heading-3-webgpu">3. WebGPU</h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686397864610/4588586f-3388-4106-b2db-35f16a788e47.jpeg" alt class="image--center mx-auto" /></p>
<p>WebGL has been the go-to solution for rendering 3D graphics on the web for over a decade. However, with the ever-increasing demand for more advanced graphics and compute capabilities, a new technology called WebGPU is emerging as its successor. WebGPU is a low-level graphics and compute API designed to provide modern, efficient, and cross-platform access to the underlying GPU hardware. In this blog post, we will explore the features and advantages of WebGPU over WebGL and discuss its potential to revolutionize web graphics rendering.</p>
<ol>
<li><p><strong>Enhanced Performance and Efficiency:</strong> One of the key advantages of WebGPU is its focus on performance and efficiency. Unlike WebGL, which is based on the OpenGL ES standard, WebGPU is designed to leverage the capabilities of modern GPUs more directly. This lower-level access allows developers to achieve better performance and more fine-grained control over the rendering pipeline, resulting in smoother and more responsive graphics.</p>
</li>
<li><p><strong>Cross-Platform Support:</strong> WebGPU aims to be a cross-platform API that works consistently across different devices and operating systems. While WebGL has varying levels of support and performance across different browsers, WebGPU aims to provide a standardized interface that works seamlessly across platforms. This will enable developers to create high-quality, immersive graphics experiences that perform consistently on a wide range of devices.</p>
</li>
<li><p><strong>Support for Advanced Graphics Features:</strong> WebGPU introduces several new features and capabilities that go beyond what WebGL offers. These include support for ray tracing, virtual reality (VR), augmented reality (AR), machine learning, and more. By exposing these advanced graphics and compute capabilities, WebGPU opens up a world of possibilities for creating visually stunning and interactive web experiences.</p>
</li>
<li><p><strong>Safety and Security:</strong> WebGPU also emphasizes safety and security. The API is designed with security in mind, implementing measures to prevent potential security vulnerabilities associated with low-level access to the GPU. Additionally, WebGPU incorporates modern memory management techniques, reducing the risk of crashes and memory-related issues.</p>
</li>
<li><p><strong>Community and Adoption:</strong> WebGPU is developed as a collaborative effort between major browser vendors, including Apple, Google, Microsoft, and Mozilla. This collaborative approach ensures that the API is designed to meet the needs of developers and is supported across a wide range of browsers. The WebGPU community is growing rapidly, with active discussions, contributions, and ongoing development to refine and expand the capabilities of the API.</p>
</li>
</ol>
<h1 id="heading-4-container-queries">4. Container Queries</h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686402739940/6a3c5a27-dedd-4387-a21f-2524f87b67d8.jpeg" alt class="image--center mx-auto" /></p>
<p>Container queries are an exciting new addition to CSS that revolutionize how we apply styles based on the size of an element's container. Instead of relying solely on media queries, which are based on viewport size, container queries allow us to target elements based on the dimensions of their containers. This offers more granular control and enables components to adapt dynamically to different container sizes.</p>
<p>To use container queries, we first need to establish a containment context on an element. This is done by applying the <code>container-type</code> property with a value of <code>size</code>, <code>inline-size</code>, or <code>normal</code>. This tells the browser that we intend to query the dimensions of the container later on.</p>
<p><strong>Consider the following example:</strong></p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"post"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Card title<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Card content<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>&gt;</span>
</code></pre>
<p>You can create a containment context using the <code>container-type</code> property:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.post</span> {
  <span class="hljs-attribute">container-type</span>: inline-size;
}
</code></pre>
<p>Once we have a containment context, we can define container queries using the <code>@container</code> at-rule. This rule applies styles to elements based on the size of the nearest ancestor with a containment context. We can also give a name to a containment context using the <code>container-name</code> property, allowing us to target a specific container in a <code>@container</code> query.</p>
<p>In the example below, a larger font size will be applied to the card title when the container's width exceeds 700px:</p>
<pre><code class="lang-css"><span class="hljs-comment">/* Default heading styles for the card title */</span>
<span class="hljs-selector-class">.card</span> <span class="hljs-selector-tag">h2</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1em</span>;
}

<span class="hljs-comment">/* If the container is larger than 700px */</span>
<span class="hljs-keyword">@container</span> (<span class="hljs-attribute">min-width:</span> <span class="hljs-number">700px</span>) {
  <span class="hljs-selector-class">.card</span> <span class="hljs-selector-tag">h2</span> {
    <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2em</span>;
  }
}

<span class="hljs-selector-class">.post</span> {
  <span class="hljs-attribute">container-type</span>: inline-size;
  <span class="hljs-attribute">container-name</span>: sidebar;
  <span class="hljs-comment">/* Shorthand container syntax */</span>
  <span class="hljs-comment">/* container: sidebar / inline-size; */</span> 
}

<span class="hljs-keyword">@container</span> sidebar (<span class="hljs-attribute">min-width:</span> <span class="hljs-number">700px</span>) {
  <span class="hljs-selector-class">.card</span> {
    <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2em</span>;
  }
}
</code></pre>
<h3 id="heading-container-query-lengths-units">Container query lengths units</h3>
<p>When applying styles to a container using container queries, you can use container query length units. These units specify a length relative to the dimensions of a query container. Components that use units of length relative to their container are more flexible to use in different containers without having to recalculate concrete length values.</p>
<p>The container query length units are:</p>
<ul>
<li><p><code>cqw</code>: 1% of a query container's width</p>
</li>
<li><p><code>cqh</code>: 1% of a query container's height</p>
</li>
<li><p><code>cqi</code>: 1% of a query container's inline size</p>
</li>
<li><p><code>cqb</code>: 1% of a query container's block size</p>
</li>
<li><p><code>cqmin</code>: The smaller value of either <code>cqi</code> or <code>cqb</code></p>
</li>
<li><p><code>cqmax</code>: The larger value of either <code>cqi</code> or <code>cqb</code></p>
<pre><code class="lang-css">  <span class="hljs-keyword">@container</span> (<span class="hljs-attribute">min-width:</span> <span class="hljs-number">700px</span>) {
    <span class="hljs-selector-class">.card</span> <span class="hljs-selector-tag">h2</span> {
      <span class="hljs-attribute">font-size</span>: <span class="hljs-built_in">max</span>(<span class="hljs-number">1.5em</span>, <span class="hljs-number">1.23em</span> + <span class="hljs-number">2</span>cqi);
    }
  }
</code></pre>
</li>
</ul>
<p>It's worth noting that container queries are still a relatively new feature and not fully supported in all browsers. However, for browsers that don't yet support container queries, we can use CSS grid and flexbox to achieve a similar effect. By using these layout techniques, we can create responsive components like the card component mentioned in your example, adapting their size and arrangement based on the available space.<br />Read more about container queries <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_container_queries"><em>here</em></a></p>
<h1 id="heading-5-color-mix">5. Color Mix</h1>
<p>The <strong>color-mix()</strong> functional notation in <strong>CSS</strong> is a powerful feature that allows developers to mix two color values and obtain the result of the mix in a specified colorspace. It provides a flexible way to create interesting color effects and transitions on web pages. Let's take a closer look at the syntax and usage of color-mix().</p>
<p>Syntax of color-mix(): The syntax of <strong>color-mix()</strong> includes the following values:</p>
<p>color-mix(<strong>color1</strong>, <strong>color2</strong>, <strong>colorspace</strong>, <strong>hue-interpolation-method</strong>, [<strong>percentage1</strong>], [<strong>percentage2</strong>])</p>
<ul>
<li><p><strong>color1 and color2:</strong> These are the two color values that will be mixed together. They can be any valid CSS color value, such as hexadecimal, RGB, HSL, or named colors.</p>
</li>
<li><p><strong>colorspace:</strong> Specifies the colorspace in which the mix will be performed. This can be one of the predefined color spaces supported by CSS, such as sRGB, linearRGB, or lab.</p>
</li>
<li><p><strong>hue-interpolation-method:</strong> Specifies how the hue values of the colors will be interpolated during the mix. The available options are <strong>linear</strong>, <strong>clock-wise</strong>, <strong>counter-clockwise</strong>, <strong>shortest</strong>, and <strong>longest</strong>.</p>
</li>
<li><p><strong>percentage1 and percentage2 (optional):</strong> These values indicate the amount of each color to be mixed. They are expressed as percentages and determine the ratio of each color in the final mix. If not provided, an equal distribution (50% each) is assumed.</p>
</li>
</ul>
<p><strong>Usage of color-mix():</strong> To use the color-mix() functional notation, you can apply it to any CSS property that accepts a color value. Here's an example of its usage:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.element</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">color-mix</span>(red, blue, sRGB, linear, <span class="hljs-number">30%</span>, <span class="hljs-number">70%</span>);
}
</code></pre>
<p>In this example, the background-color of the .element will be a mix of red and blue colors, performed in the sRGB colorspace using a linear hue interpolation method. The resulting mix will contain 30% red and 70% blue, creating a unique color blend.</p>
<h1 id="heading-6-css-nesting">6. CSS Nesting</h1>
<p>CSS Nesting is a feature that enables developers to nest CSS rules within their parent selectors. This nesting mimics the HTML structure and helps organize styles in a hierarchical manner. Previously, developers had to rely on preprocessors like SCSS to achieve this nesting functionality. However, with CSS Nesting becoming a native feature, it is now possible to utilize this powerful technique directly in CSS.</p>
<p><strong>Browser Support:</strong></p>
<p><a target="_blank" href="https://caniuse.com/css-nesting"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686465697411/9a3d2fa3-8b54-4bfb-bd30-734db264c295.png" alt class="image--center mx-auto" /></a></p>
<p><strong>Benefits of CSS Nesting:</strong></p>
<ol>
<li><p><strong>Improved Code Organization:</strong> CSS Nesting allows developers to group related styles together, making it easier to locate and modify specific styles. Instead of scattering styles across the stylesheet, nesting brings them closer, reducing code redundancy and enhancing code organization.</p>
</li>
<li><p><strong>Enhanced Readability:</strong> By mirroring the HTML structure, nested CSS rules provide better context and readability. Developers can easily identify the relationship between selectors and understand the hierarchy of styles, resulting in more maintainable and intuitive code.</p>
</li>
<li><p><strong>Modular Stylesheets:</strong> Nesting promotes modularity in CSS. Styles that are specific to a particular component or section can be grouped together within a parent selector, encapsulating them and making stylesheets more modular and reusable.</p>
</li>
<li><p><strong>Efficient Media Query Integration:</strong> CSS Nesting simplifies the integration of media queries. Previously, developers had to repeat selectors for different media queries, leading to redundant code. With nesting, media queries can be nested within the corresponding selector, reducing duplication and enhancing efficiency.</p>
</li>
</ol>
<p><strong>Using CSS Nesting:</strong> CSS Nesting utilizes the nesting selector syntax, which includes the <code>&amp;</code> character to refer to the parent selector. Here's an example of how CSS Nesting can be applied:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.parent</span> {
  <span class="hljs-comment">/* Parent styles */</span>

  &amp; .child {
    <span class="hljs-comment">/* Nested child styles */</span>
  }

  &amp; <span class="hljs-selector-class">.sibling</span> {
    <span class="hljs-comment">/* Nested sibling styles */</span>
  }
}
</code></pre>
<p>In the above example, the <code>.child</code> and <code>.sibling</code> styles are nested within the <code>.parent</code> selector using the <code>&amp;</code> syntax. This approach provides a clear and concise representation of the hierarchical relationship between selectors.</p>
<h1 id="heading-7-color-fonts">7. Color Fonts</h1>
<p>Color fonts, also known as chromatic or multicolor fonts, are typefaces that incorporate graphic properties within the font file itself. Unlike traditional fonts that consist of outline shapes, color fonts include additional information such as bitmap images, vector shapes, gradients, textures, and even animations. These fonts break free from the limitations of monochromatic glyphs, allowing designers to unleash their creativity and explore new visual possibilities.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686466353262/15c96b13-809c-4484-8069-802a0bce8d54.webp" alt class="image--center mx-auto" /></p>
<ol>
<li><p><strong>Visual Interest:</strong> Color fonts offer a visually engaging typography experience, allowing designers to captivate their audience with vibrant colors, gradients, and textures. By leveraging these elements, you can create eye-catching headlines, logos, and other textual elements that demand attention.</p>
</li>
<li><p><strong>Personalization:</strong> Color fonts provide an excellent opportunity to infuse your design with personality and establish a unique brand identity. By incorporating specific color schemes and visual styles into your typography, you can reinforce brand recognition and create a cohesive visual experience.</p>
</li>
<li><p><strong>Accessibility:</strong> Color fonts are compatible with assistive technologies, making them accessible to users with disabilities. They can be read by screen readers and support copy-and-paste and find-in-page functionality, ensuring that your content remains inclusive and available to all users.</p>
</li>
</ol>
<p><strong>Considerations when Using Color Fonts:</strong></p>
<ol>
<li><p><strong>Scalability:</strong> While color bitmap fonts can scale correctly up to a specific size, they may appear pixelated beyond that point. It's essential to test and optimize the font size to maintain optimal visual quality.</p>
</li>
<li><p><strong>File Size:</strong> Color font files tend to be larger than traditional fonts due to the additional graphical information they contain. Consider the impact on page loading times and choose the appropriate file formats and compression techniques to mitigate this issue.</p>
</li>
<li><p><strong>Contrast and Legibility:</strong> Ensure that your color fonts maintain sufficient contrast against the background to ensure readability. Test the font on different devices and screen sizes to verify its legibility across various contexts.</p>
</li>
</ol>
<p><strong>Utilizing Color Fonts:</strong></p>
<ol>
<li><p><strong>Selection:</strong> Choose color fonts that align with your design objectives and complement your overall aesthetic. Many reputable font foundries and online platforms offer a wide range of free and premium color fonts to choose from.</p>
</li>
<li><p><strong>Implementation:</strong> Incorporate color fonts into your web designs using the <code>@font-face</code> rule in CSS. Import the font file and apply it to the desired web elements to enjoy the visual richness it offers.</p>
</li>
<li><p><strong>Balance and Contrast:</strong> Avoid overusing color fonts and ensure that they harmonize with the overall design. Pay attention to the contrast between the font and the background to maintain legibility and readability.</p>
</li>
</ol>
<h1 id="heading-8-web-vitals-extension-for-chromehttpschromegooglecomwebstoredetailweb-vitalsahfhijdlegdabablpippeagghigmibma"><a target="_blank" href="https://chrome.google.com/webstore/detail/web-vitals/ahfhijdlegdabablpippeagghigmibma">8. Web Vitals Extension For Chrome</a></h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686467165641/75a4a874-46f7-4b0e-b650-5a5381d9dfc7.jpeg" alt class="image--center mx-auto" /></p>
<p>As web developers, we strive to deliver exceptional user experiences by optimizing the performance of our websites. To aid in this endeavor, Google has introduced the Web Vitals extension, a powerful tool that allows developers to assess and diagnose performance issues directly from the browser. We will explore the features of the Web Vitals extension, understand how it works internally, and discover how it helps identify specific elements causing performance bottlenecks.</p>
<p>The Web Vitals extension is a browser extension available for Google Chrome that integrates with the Chrome DevTools. It provides real-time insights into various performance metrics, helping developers measure, analyze, and improve the user experience of their web applications. The extension focuses on three core web vitals metrics: <strong>Largest Contentful Paint</strong> (LCP), <strong>First Input Delay</strong> (FID), and <strong>Cumulative Layout Shift</strong> (CLS).</p>
<p><strong>Key Features of the Web Vitals Extension:</strong></p>
<ol>
<li><p><strong>Performance Analysis:</strong> The Web Vitals extension displays comprehensive performance metrics for individual pages, allowing developers to assess the overall performance of their website. It provides insights into LCP, FID, and CLS scores, along with detailed breakdowns and suggestions for improvement.</p>
</li>
<li><p><strong>Element-Level Performance Tracking:</strong> One of the most powerful features of the Web Vitals extension is its ability to pinpoint specific elements causing performance issues. By selecting an element on the page, developers can analyze the associated metrics, such as element-level <strong>LCP</strong>, <strong>FID</strong>, and <strong>CLS</strong> scores, helping them identify and address performance bottlenecks more effectively.</p>
</li>
<li><p><strong>Real-Time Monitoring:</strong> The extension constantly monitors web vitals metrics as users interact with the website, providing real-time feedback on performance changes. This feature enables developers to identify performance regressions and quickly take corrective actions.</p>
</li>
<li><p><strong>Diagnostic Information:</strong> The Web Vitals extension offers diagnostic information and actionable recommendations to help developers understand the underlying causes of performance issues. It suggests best practices and optimizations specific to the identified problems, empowering developers to make informed decisions for improving performance.</p>
</li>
</ol>
<p><strong>How the Web Vitals Extension Works:</strong> The Web Vitals extension leverages the browser's native Performance API, which captures various performance metrics during page loading and user interactions. It utilizes this data to calculate the LCP, FID, and CLS scores. By analyzing the timing and interaction data collected by the Performance API, the extension identifies the elements responsible for specific performance issues.</p>
<p>When a developer selects an element using the extension's inspection tool, it uses various techniques, such as element size and position tracking, event handling, and DOM mutation monitoring, to determine the element-level performance metrics. These metrics provide granular insights into how individual elements impact overall page performance.</p>
<h1 id="heading-now-lets-talk-about-some-javascript-features"><em>Now let's talk about some javascript features</em></h1>
<h1 id="heading-9-javascript-arrayat-1">9. Javascript <code>Array.at(-1)</code></h1>
<p>The <a target="_blank" href="http://Array.at"><code>Array.at</code></a><code>()</code> method is a relatively new addition to JavaScript, it allows you to access an element from an array by using a negative index, effectively retrieving elements from the end of the array.</p>
<p>To access the last element of an array using <a target="_blank" href="http://Array.at"><code>Array.at</code></a><code>(-1)</code>, you can follow this code example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> arr = [<span class="hljs-string">'apple'</span>, <span class="hljs-string">'banana'</span>, <span class="hljs-string">'orange'</span>];
<span class="hljs-keyword">const</span> lastElement = arr.at(<span class="hljs-number">-1</span>);
<span class="hljs-keyword">const</span> secondLastElement = arr.at(<span class="hljs-number">-2</span>);
<span class="hljs-keyword">const</span> thirdLastElement = arr.at(<span class="hljs-number">-3</span>);

<span class="hljs-built_in">console</span>.log(lastElement); <span class="hljs-comment">// Output: 'orange'</span>
<span class="hljs-built_in">console</span>.log(secondLastElement); <span class="hljs-comment">// Output: 'banana'</span>
<span class="hljs-built_in">console</span>.log(thirdLastElement); <span class="hljs-comment">// Output: 'apple'</span>
</code></pre>
<h1 id="heading-10-javascript-structuredclone-method">10. Javascript <code>structuredClone()</code> method</h1>
<p>It allows you to create a deep copy of an object, including complex data types like dates, regular expressions, and more.</p>
<p>To use the <code>structuredClone</code> method to copy an object, you can follow this code example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> obj = { <span class="hljs-attr">name</span>: <span class="hljs-string">'John'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">30</span> };
<span class="hljs-keyword">const</span> copy = structuredClone(obj);

<span class="hljs-built_in">console</span>.log(copy); <span class="hljs-comment">// Output: { name: 'John', age: 30 }</span>
</code></pre>
<p>In the above example, we have an object <code>obj</code> with properties <code>name</code> and <code>age</code>. By calling <code>structuredClone(obj)</code>, we create a deep copy of the object and assign it to the <code>copy</code> variable. The <code>copy</code> object will have the same properties and values as the original <code>obj</code>.</p>
<p>Before the introduction of the <code>structuredClone</code> method, deep copying an object in JavaScript was a bit more complicated. Developers would typically use methods like <code>JSON.stringify</code> and <code>JSON.parse</code> to accomplish this. Here's an example of how it was done before the <code>structuredClone</code> method:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> obj = { <span class="hljs-attr">name</span>: <span class="hljs-string">'John'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">30</span> };
<span class="hljs-keyword">const</span> copy = <span class="hljs-built_in">JSON</span>.parse(<span class="hljs-built_in">JSON</span>.stringify(obj));

<span class="hljs-built_in">console</span>.log(copy); <span class="hljs-comment">// Output: { name: 'John', age: 30 }</span>
</code></pre>
<p>In the previous approach, <code>JSON.stringify(obj)</code> converts the object to a JSON string representation, and <code>JSON.parse()</code> then parses the JSON string back into an object, effectively creating a deep copy. However, this method has some limitations. It doesn't support complex data types like dates, regular expressions, or functions. Additionally, it discards undefined properties, converts numbers to strings, and loses object references.</p>
<p>The <code>structuredClone</code> method, on the other hand, is designed to handle complex data types and create an exact replica of the original object, including all its properties and references.</p>
<h1 id="heading-11-transform-stream">11. Transform Stream</h1>
<p>The <code>TransformStream</code> interface in the Streams API allows you to pipe the output of one fetch call into another. This can be useful when you need to transform or modify the data received from a server before sending it to another server or processing it further.</p>
<p>Here's an example of how you can pipe one fetch call into another using <code>TransformStream</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Create a new TransformStream</span>
<span class="hljs-keyword">const</span> transformStream = <span class="hljs-keyword">new</span> TransformStream();

<span class="hljs-comment">// Get the readable and writable ends of the transform stream</span>
<span class="hljs-keyword">const</span> { readable, writable } = transformStream;

<span class="hljs-comment">// Create a fetch request</span>
<span class="hljs-keyword">const</span> request1 = fetch(<span class="hljs-string">'https://api.example.com/data'</span>);

<span class="hljs-comment">// Pipe the response from the first fetch call into the transform stream</span>
request1
  .then(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> response.body.pipeTo(writable))
  .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">'Error:'</span>, error));

<span class="hljs-comment">// Create a new fetch request using the transformed data from the first fetch call</span>
<span class="hljs-keyword">const</span> request2 = fetch(<span class="hljs-string">'/api/endpoint'</span>, {
  <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
  <span class="hljs-attr">body</span>: readable
});

<span class="hljs-comment">// Process the response from the second fetch call</span>
request2
  .then(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> response.json())
  .then(<span class="hljs-function"><span class="hljs-params">data</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Data:'</span>, 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">'Error:'</span>, error));
</code></pre>
<p>In this example, we create a <code>TransformStream</code> and get its <strong>readable</strong> and <strong>writable</strong> ends. We then initiate a fetch request (<code>request1</code>) to retrieve data from an API endpoint. Instead of directly consuming the <strong>response</strong>, we pipe the response body into the <strong>writable</strong> end of the <code>TransformStream</code>.</p>
<p>The transform stream allows us to apply any necessary transformations or modifications to the data received from the first fetch call. These transformations can be defined by implementing a transform function that takes chunks of input data and produces transformed output data. The specifics of the transformation logic will depend on your use case.</p>
<p>Once the transformation is complete, we initiate a <strong>second fetch request</strong> (<code>request2</code>) using the transformed data from the <strong>readable</strong> end of the transform stream. This allows us to send the modified data to another <strong>server</strong> or process it further as needed.</p>
<p>By using <code>TransformStream</code> to pipe the output of one fetch call into another, you can efficiently handle <strong>data transformation</strong> and <strong>chaining</strong> of multiple asynchronous operations. This provides greater flexibility and control over how data is processed and transmitted in your application.</p>
<h1 id="heading-12-import-maps">12. Import Maps</h1>
<p><strong>Import maps</strong> in JavaScript is a feature that allows you to declare a collection of JavaScript <strong>modules</strong> and their associated URLs all at once. It provides a way to map module specifiers to specific URLs, enabling you to easily manage and organize your module dependencies.</p>
<p>With import maps, you can define a map of module specifiers and their corresponding URLs in a JavaScript file called an <strong>"import map"</strong>. This map acts as a central configuration for your module imports, making it easier to maintain and update module <strong>dependencies</strong> across your application.</p>
<p>Here's an example of how import maps are used:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// import-map.js</span>
<span class="hljs-keyword">const</span> importMap = {
  <span class="hljs-attr">imports</span>: {
    <span class="hljs-string">'module-a'</span>: <span class="hljs-string">'/path/to/module-a.js'</span>,
    <span class="hljs-string">'module-b'</span>: <span class="hljs-string">'/path/to/module-b.js'</span>,
    <span class="hljs-string">'module-c'</span>: <span class="hljs-string">'/path/to/module-c.js'</span>
  }
};

<span class="hljs-comment">// main.js</span>
<span class="hljs-keyword">import</span> { foo } <span class="hljs-keyword">from</span> <span class="hljs-string">'module-a'</span>;
<span class="hljs-keyword">import</span> { bar } <span class="hljs-keyword">from</span> <span class="hljs-string">'module-b'</span>;
<span class="hljs-keyword">import</span> { baz } <span class="hljs-keyword">from</span> <span class="hljs-string">'module-c'</span>;

<span class="hljs-comment">// index.html</span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"importmap"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/path/to/import-map.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/path/to/main.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>
</code></pre>
<p>Using import maps offers several benefits. It centralizes and simplifies the management of module dependencies by providing a single configuration file. It also allows for easier refactoring and updating of module URLs since changes can be made in the import map without modifying individual import statements throughout the codebase.</p>
<p>Import maps are supported in modern browsers, but it's important to note that they are still considered an experimental feature and may not be available in all environments or older browsers. Therefore, it's recommended to check the browser compatibility before relying on import maps in production applications.</p>
<h1 id="heading-13-json-modules-of-tc39-proposal">13. JSON Modules of TC39 proposal</h1>
<p>The <strong>TC39 proposal</strong> we are referring to is called "<strong>JSON Modules</strong>" or "i<strong>mport assertions</strong>." It is an ongoing proposal to enhance the JavaScript module system by allowing direct importing of JSON data into JavaScript files.</p>
<p>Currently, in <strong>JavaScript</strong>, when you import a JSON file, it is treated as a regular JavaScript <strong>module</strong>. You need to explicitly parse the JSON data using <code>JSON.parse()</code> to access the actual JSON object. The JSON <strong>Modules</strong> proposal aims to simplify this process by enabling direct import of JSON as a first-class module type.</p>
<p>Here's an example of how JSON Modules would work:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// data.json</span>
{
  <span class="hljs-string">"name"</span>: <span class="hljs-string">"John Doe"</span>,
  <span class="hljs-string">"age"</span>: <span class="hljs-number">30</span>,
  <span class="hljs-string">"city"</span>: <span class="hljs-string">"New York"</span>
}

<span class="hljs-comment">// main.js</span>
<span class="hljs-keyword">import</span> data <span class="hljs-keyword">from</span> <span class="hljs-string">'./data.json'</span> assert { <span class="hljs-attr">type</span>: <span class="hljs-string">'json'</span> };

<span class="hljs-built_in">console</span>.log(data.name); <span class="hljs-comment">// "John Doe"</span>
<span class="hljs-built_in">console</span>.log(data.age); <span class="hljs-comment">// 30</span>
<span class="hljs-built_in">console</span>.log(data.city); <span class="hljs-comment">// "New York"</span>
</code></pre>
<p>The JSON Modules proposal simplifies the process of importing and working with JSON data in JavaScript. It eliminates the need for explicit parsing and provides a more intuitive and streamlined way to import JSON into your code.</p>
<p>It's important to note that the JSON Modules proposal is still a stage 2 proposal in the TC39 process at the time of my knowledge cutoff. This means it is actively being discussed and evaluated, but it has not yet reached the final stage of standardization. As with any proposal, it may undergo changes before it becomes an official part of the JavaScript language. Therefore, it's crucial to stay updated on the status and adoption of the proposal in order to determine its availability in your specific JavaScript environment.</p>
<h1 id="heading-14-transform-props">14. Transform Props</h1>
<p>Now we also have individual CSS transform properties</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.element</span> {
  <span class="hljs-attribute">translate</span>: <span class="hljs-number">69%</span> <span class="hljs-number">0</span>;
  <span class="hljs-attribute">rotate</span>: <span class="hljs-number">69deg</span>;
  <span class="hljs-attribute">scale</span>: <span class="hljs-number">1.5</span>;
}
</code></pre>
<p>it's important to note that the individual transform properties are part of the CSS <code>transform</code> property, which is supported by modern web browsers. However, older browsers may have limited or no support for these properties. Therefore, it's essential to consider browser compatibility and provide fallbacks or alternative approaches for older browser versions if needed.</p>
<h1 id="heading-15-trig-functions">15. Trig Functions</h1>
<p>We have new trigonometric functions in CSS, which is incredibly useful if we have circles in our design.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686474010756/b3c0c588-25b4-4ffb-aea3-444a5b05d780.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-css"><span class="hljs-selector-class">.circum-size</span> {
    <span class="hljs-attribute">translate</span>: 
            <span class="hljs-built_in">calc</span>(cos(<span class="hljs-number">30deg</span>) * <span class="hljs-number">100px</span>)
            <span class="hljs-built_in">calc</span>(sin(<span class="hljs-number">30deg</span>) * <span class="hljs-number">100px</span> * -<span class="hljs-number">1</span>);
}
</code></pre>
<p>The core three trig functions are:</p>
<ul>
<li><p><code>cos()</code> : Returns the cosine of an angle, which is a value between <code>-1</code> and <code>1</code> .</p>
</li>
<li><p><code>sin()</code> : Returns the sine of an angle, which is a value between <code>-1</code> and <code>1</code> .</p>
</li>
<li><p><code>tan()</code> : Returns the tangent of an angle, which is a value between <code>-∞</code> and <code>+∞</code>.</p>
</li>
</ul>
<p>Read more <a target="_blank" href="https://web.dev/css-trig-functions/"><strong><em>here</em></strong></a></p>
<h1 id="heading-16-initial-letter">16. Initial Letter</h1>
<p>There is also a CSS property called <code>initial-letter</code> that allows us to manipulate the first letter of an article or block of text, similar to the way it is done in a magazine. By using the <code>initial-letter</code> property, we can increase the size of the first letter to create a visually appealing and attention-grabbing effect.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686474565938/825a6ebe-4f63-446c-8a76-5540f651cab6.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-css"><span class="hljs-selector-class">.article</span> {
    <span class="hljs-attribute">initial-letter</span>: <span class="hljs-number">5</span> <span class="hljs-number">4</span>;
}
</code></pre>
<p>Read more <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/initial-letter"><strong><em>here</em></strong></a></p>
<h1 id="heading-17-viewport-units">17. Viewport Units</h1>
<p>We also now have new viewport units specifically designed for mobile devices, which consider the presence of opened toolbars. These new units, such as <code>lvh</code>,<code>lvw</code>, <code>svw</code> and <code>svh</code> allow us to create layouts and designs that adapt seamlessly to different screen sizes, while taking into account the space occupied by toolbars when they are opened. This ensures that our web pages and applications remain fully responsive and optimized for mobile users, providing a better user experience.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686475036664/3db99a07-43c4-4da1-bf43-a8a34b386a1f.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-css"><span class="hljs-selector-class">.article</span> {
    <span class="hljs-attribute">height</span>: <span class="hljs-number">100</span>lvh;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">100s</span>vw;
}
</code></pre>
<p>Read more <a target="_blank" href="https://web.dev/viewport-units/"><strong><em>here</em></strong></a></p>
<h1 id="heading-18-focus-visible">18. focus-visible:</h1>
<p>In the realm of accessibility, it's important to prioritize user experience for individuals who rely on assistive technologies or keyboard navigation. That's where the <code>focus-visible</code> pseudo-class comes into play. Unlike the traditional <code>:focus</code> pseudo-class, which applies styling to all focused elements, <code>focus-visible</code> specifically targets elements that receive focus from non-mouse inputs (such as keyboard navigation). This ensures that focus styles are only visible when they are needed, making the user interface more intuitive and reducing visual noise. By utilizing <code>focus-visible</code>, we can create a more accessible and inclusive experience for all users, especially those with disabilities or limited dexterity.</p>
<pre><code class="lang-css"><span class="hljs-comment">/* focus with tab key  */</span>
<span class="hljs-selector-class">.btn</span><span class="hljs-selector-pseudo">:focus-visible</span> {
  <span class="hljs-attribute">outline</span>: <span class="hljs-number">2px</span> solid darkkhaki;
}

<span class="hljs-comment">/* mouse click  */</span>
<span class="hljs-selector-class">.btn</span><span class="hljs-selector-pseudo">:focus</span><span class="hljs-selector-pseudo">:not(</span><span class="hljs-selector-pseudo">:focus-visible)</span> {
  <span class="hljs-attribute">outline</span>: none;
}
</code></pre>
<h1 id="heading-19-inert">19. Inert</h1>
<p>The <code>inert</code> property is a new addition to CSS that allows us to indicate that certain elements are incapable of receiving focus or being interacted with. By applying the <code>inert</code> property to specific elements, such as static or non-interactive components, we can visually convey that they lack the ability to be focused on, eliminating any potential confusion for users. While the visual appearance may appear "boring" or less interactive, it serves as an important visual cue, making it clear to users that these elements are not intended for direct interaction. The <code>inert</code> property proves to be a valuable tool in managing focus and providing a more intuitive user experience by ensuring that interactive elements stand out while non-interactive ones gracefully recede into the background.</p>
<pre><code class="lang-css">&lt;<span class="hljs-selector-tag">div</span>&gt;
  &lt;<span class="hljs-selector-tag">label</span> <span class="hljs-selector-tag">for</span>="<span class="hljs-selector-tag">button1</span>"&gt;<span class="hljs-selector-tag">Button</span> 1&lt;/<span class="hljs-selector-tag">label</span>&gt;
  &lt;<span class="hljs-selector-tag">button</span> <span class="hljs-selector-tag">id</span>="<span class="hljs-selector-tag">button1</span>"&gt;<span class="hljs-selector-tag">I</span> <span class="hljs-selector-tag">am</span> <span class="hljs-selector-tag">not</span> <span class="hljs-selector-tag">inert</span>&lt;/<span class="hljs-selector-tag">button</span>&gt;
&lt;/<span class="hljs-selector-tag">div</span>&gt;
&lt;<span class="hljs-selector-tag">div</span> <span class="hljs-selector-tag">inert</span>&gt;
  &lt;<span class="hljs-selector-tag">label</span> <span class="hljs-selector-tag">for</span>="<span class="hljs-selector-tag">button2</span>"&gt;<span class="hljs-selector-tag">Button</span> 2&lt;/<span class="hljs-selector-tag">label</span>&gt;
  &lt;<span class="hljs-selector-tag">button</span> <span class="hljs-selector-tag">id</span>="<span class="hljs-selector-tag">button2</span>"&gt;<span class="hljs-selector-tag">I</span> <span class="hljs-selector-tag">am</span> <span class="hljs-selector-tag">inert</span>&lt;/<span class="hljs-selector-tag">button</span>&gt;
&lt;/<span class="hljs-selector-tag">div</span>&gt;

<span class="hljs-comment">/* CSS */</span>
<span class="hljs-selector-attr">[inert]</span> &gt; * {
  <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0.5</span>;
}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686476178117/06e5b3b4-882a-49cf-84b1-98c665fd5e19.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-20-view-transition-api">20. View Transition API</h1>
<p>The View Transition API is an exciting new addition to the web development landscape, offering the ability to create captivating page transitions that were previously only available in native mobile apps. With this API, developers can now achieve seamless and visually appealing transitions between pages in single-page applications (SPAs), with future plans to extend support to all same-origin pages.</p>
<p>The core animation effect provided by the View Transition API is a simple cross-fade between the current page and the incoming page. However, the true power of this API lies in its flexibility, allowing developers to create more complex and dynamic transitions using CSS or JavaScript. By taking snapshots of the current and incoming pages, developers can animate specific elements or layers separately, enabling a wide range of transition effects beyond simple fades.</p>
<p>It's important to note that the View Transition API is currently only partially supported in Chromium-based browsers. While this limits its immediate usability, developers can still experiment with the API and leverage it in controlled environments like Electron projects. As the web continues its journey toward offering native-like experiences, features like the View Transition API play a crucial role in making progressive web apps (PWAs) and websites feel more fluid and engaging.</p>
<p>The author recommends checking for API support and implementing fallback solutions for browsers that do not support it. However, they express a desire to avoid excessive JavaScript checks for legacy browser compatibility. Once full support for page-to-page transitions is available in at least one browser, it will become much easier to adopt the View Transition API by simply adding a small amount of CSS that can be safely ignored by legacy browsers. Until then, developers are encouraged to explore and prepare for the eventual widespread adoption of this exciting feature.</p>
<p>Read more <a target="_blank" href="https://dev.to/link2twenty/view-transitions-api-5980"><strong><em>here</em></strong></a></p>
<h1 id="heading-21-animation-timeline">21. Animation Timeline</h1>
<p>The <code>animation-timeline</code> CSS property is a powerful feature that allows developers to control the progress of an animation by specifying a timeline. This timeline can be associated with the current position on a scrollbar, known as a scrollbar timeline.</p>
<p>There are two types of scroll timelines that can be used with the <code>animation-timeline</code> property: named scroll timelines and anonymous scroll timelines. A named scroll timeline is explicitly defined by applying the <code>scroll-timeline-name</code> property to an element and giving it a custom identifier. On the other hand, an anonymous scroll timeline is set using the <code>scroll()</code> functional notation. This notation indicates that the timeline is provided by some ancestor element of the current element.</p>
<p>The <code>animation-timeline</code> property can be set individually, or it can be included as part of the <code>animation</code> shorthand property. When set to <code>none</code>, the animation is not associated with any timeline. Setting it to <code>auto</code> means that the animation's timeline is determined by the document's default <code>DocumentTimeline</code>.</p>
<p>To provide a named scroll timeline, you can define a scroll timeline with a specific name using the <code>scroll-timeline-name</code> property on an element. For example, you can create a scroll timeline named <code>squareTimeline</code> on an element with the id <code>container</code>. Then, you can apply this named scroll timeline to an animation on the <code>#square</code> element using the <code>animation-timeline: squareTimeline</code> declaration.</p>
<p>For anonymous scroll timelines, you can use the <code>scroll()</code> functional notation to indicate that the timeline is provided by the nearest parent element that has a scrollbar. This notation allows you to animate an element based on the position of the scrollbar. The anonymous scrollbar timeline is applied to the element using the <code>animation-timeline</code> property.</p>
<p>It's important to note that the <code>scroll()</code> functional notation is still experimental, and browser support may vary. The examples provided demonstrate how to use both named and anonymous scroll timelines, allowing you to create more advanced and interactive animations that are synchronized with scroll positions.</p>
<p>Overall, the <code>animation-timeline</code> CSS property provides a powerful mechanism to control animations based on scroll positions, offering more flexibility and interactivity in web animations.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
  <span class="hljs-comment">/* Define a named scroll timeline */</span>
  <span class="hljs-selector-id">#container</span> {
    <span class="hljs-attribute">scroll-timeline-name</span>: squareTimeline;
    <span class="hljs-attribute">overflow</span>: scroll;
    <span class="hljs-attribute">height</span>: <span class="hljs-number">200px</span>;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">200px</span>;
  }

  <span class="hljs-comment">/* Apply the named scroll timeline to the animation */</span>
  <span class="hljs-selector-id">#square</span> {
    <span class="hljs-attribute">animation</span>: moveSquare <span class="hljs-number">3s</span> infinite;
    <span class="hljs-attribute">animation-timeline</span>: squareTimeline;
    <span class="hljs-attribute">background-color</span>: red;
    <span class="hljs-attribute">height</span>: <span class="hljs-number">50px</span>;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">50px</span>;
  }

  <span class="hljs-comment">/* Define keyframes for the animation */</span>
  <span class="hljs-keyword">@keyframes</span> moveSquare {
    0% { <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateX</span>(<span class="hljs-number">0</span>); }
    100% { <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateX</span>(<span class="hljs-number">300px</span>); }
  }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"container"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</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">div</span>&gt;</span>
</code></pre>
<p>In this example, we have a container element with the id <code>container</code>, which represents the named scroll timeline called <code>squareTimeline</code>. We set the <code>scroll-timeline-name</code> property on this element and give it a scrollbar by applying the <code>overflow: scroll</code> style. The container has a fixed height and width to demonstrate scrolling.</p>
<p>Inside the container, we have a square element with the id <code>square</code>. We define an animation called <code>moveSquare</code> using <code>@keyframes</code>, which moves the square from left to right. To associate this animation with the named scroll timeline, we set <code>animation-timeline: squareTimeline</code> on the square element. The animation is set to run indefinitely with <code>animation: moveSquare 3s infinite</code>.</p>
<p>As a result, the square element will move horizontally within the container as the scrollbar is scrolled. The animation is synchronized with the scroll position on the named scroll timeline, providing an interactive and dynamic effect.</p>
<p>You can experiment with this code and observe how the square element animates based on the scroll position within the container.</p>
<p><strong>This blog is inspired by</strong> <a target="_blank" href="https://www.youtube.com/watch?v=q1fsBWLpYW4&amp;t=35s"><strong><em>Fireship's video</em></strong></a></p>
<p><strong>If you found this blog helpful or inspiring, show your support by hitting the like button! ❤️</strong><br /><strong>I'll keep bringing such type of content.</strong></p>
]]></content:encoded></item><item><title><![CDATA[Simplifying State Management with Zustand]]></title><description><![CDATA[Zustand the brainchild of Jotai and React-spring, is a state management gem you can't bear to ignore. Here are the impressive stats that speak for themselves:
🌟 A stellar 31,000+ GitHub stars.
💥 A whopping 37 million downloads and counting.
📦 A mi...]]></description><link>https://blog.hemant.lol/zustand</link><guid isPermaLink="true">https://blog.hemant.lol/zustand</guid><category><![CDATA[State Management ]]></category><category><![CDATA[zustand]]></category><category><![CDATA[React]]></category><category><![CDATA[Next.js]]></category><dc:creator><![CDATA[Hemant]]></dc:creator><pubDate>Tue, 30 May 2023 17:35:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1685466349178/dd09102a-a4e3-45ea-b26e-3a98c6a8324b.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a target="_blank" href="https://github.com/pmndrs/zustand"><strong>Zustand</strong></a> the brainchild of Jotai and React-spring, is a state management gem you can't bear to ignore. Here are the impressive stats that speak for themselves:</p>
<p>🌟 A stellar 31,000+ GitHub stars.</p>
<p>💥 A whopping 37 million downloads and counting.</p>
<p>📦 A minuscule bundle size of only <strong>1.16kb</strong>.</p>
<p>⚡️ Over a million n' half weekly downloads, proving its widespread adoption.</p>
<p>So, if the thought of exploring a new frontend tool sends shivers down your spine, these impressive stats should sway you towards giving Zustand a try. It's a lightweight powerhouse that delivers exceptional performance and state management prowess.</p>
<h1 id="heading-1-simplicity"><strong>1. Simplicity</strong>:</h1>
<p>Zustand provides a simple and intuitive API, making it easy to understand and use. It eliminates the need for complex setup and boilerplate code, allowing developers to focus on their application logic.</p>
<h1 id="heading-2-minimalistic"><strong>2. Minimalistic</strong>:</h1>
<p>Zustand has a small footprint and minimal bundle size, resulting in faster loading times and improved performance. It avoids unnecessary abstractions and layers, providing a lightweight state management solution.</p>
<h1 id="heading-3-performance"><strong>3. Performance</strong>:</h1>
<p>Zustand leverages a minimal reactivity model and selective updates. It only re-renders components that depend on the changed state, optimizing performance by reducing unnecessary renders. This approach can lead to better application performance, especially in large-scale applications.</p>
<h1 id="heading-4-flexibility"><strong>4. Flexibility</strong>:</h1>
<p>Zustand offers flexibility in structuring and organizing state. Developers can use simple objects, classes, or any other data structure to define and manage state. It allows granular control over state updates and encourages a more modular and composable approach.</p>
<h1 id="heading-5-type-safety"><strong>5. Type Safety</strong>:</h1>
<p>Zustand has excellent TypeScript support, providing type safety and enhanced code quality. Developers can benefit from static type checking, autocompletion, and better documentation, reducing the likelihood of runtime errors and improving overall development productivity.</p>
<h1 id="heading-6-developer-experience"><strong>6. Developer Experience</strong>:</h1>
<p>Zustand integrates well with popular development tools, such as React DevTools and Redux DevTools Extension. It offers a great developer experience with features like time-travel debugging, hot module replacement, and easy debugging of state changes.</p>
<h1 id="heading-7-scalability"><strong>7. Scalability</strong>:</h1>
<p>Zustand is suitable for small to large-scale applications. It provides features like derived state, middleware support, and selectors, enabling developers to efficiently manage complex state structures and scale their applications without sacrificing performance.</p>
<h1 id="heading-8-react-hooks-compatibility"><strong>8. React Hooks Compatibility</strong>:</h1>
<p>Zustand seamlessly integrates with React Hooks, allowing developers to leverage the power of Hooks for managing state. It follows the React philosophy of functional components and embraces the declarative nature of React.</p>
<h1 id="heading-9-active-community"><strong>9. Active Community</strong>:</h1>
<p>Zustand has a growing and active community, with regular updates and contributions from developers worldwide. The community provides support, shares knowledge, and creates extensions and plugins, enhancing the ecosystem around Zustand.</p>
<h1 id="heading-example-code">Example Code:</h1>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { create } <span class="hljs-keyword">from</span> <span class="hljs-string">'zustand'</span>;

<span class="hljs-comment">// Define the store type</span>
<span class="hljs-keyword">type</span> CounterStore = {
  count: <span class="hljs-built_in">number</span>;
  increment: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;
  decrement: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;
};

<span class="hljs-comment">// Create the Zustand store</span>
<span class="hljs-keyword">const</span> useCounterStore = create&lt;CounterStore&gt;(<span class="hljs-function">(<span class="hljs-params">set</span>) =&gt;</span> ({
  count: <span class="hljs-number">0</span>,
  increment: <span class="hljs-function">() =&gt;</span> set(<span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> ({ count: state.count + <span class="hljs-number">1</span> })),
  decrement: <span class="hljs-function">() =&gt;</span> set(<span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> ({ count: state.count - <span class="hljs-number">1</span> })),
}));

<span class="hljs-comment">// Component using the Zustand store</span>
<span class="hljs-keyword">const</span> Counter: React.FC = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> [ count, increment, decrement ] = useCounterStore(
        <span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> [ state.count, state.increment, state.decrement ]
    );

  <span class="hljs-keyword">return</span> (
    &lt;div&gt;
      &lt;h2&gt;Count: {count}&lt;/h2&gt;
      &lt;button onClick={increment}&gt;Increment&lt;/button&gt;
      &lt;button onClick={decrement}&gt;Decrement&lt;/button&gt;
    &lt;/div&gt;
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Counter;
</code></pre>
<p>In this example, we create a Zustand store using the <code>create</code> function, defining an initial state and actions to modify the state. The <code>useCounterStore</code> hook provides access to the store's state and actions.</p>
<p>Within the <code>Counter</code> component, we use the <code>useCounterStore</code> hook to retrieve the <code>count</code> state value and the <code>increment</code> and <code>decrement</code> actions. Any modifications to the state trigger automatic re-renders of the component, ensuring a reactive UI.</p>
<p>This concise and declarative approach to state management is one of the many benefits of Zustand. It eliminates the need for complex setup and boilerplate code, allowing developers to focus on building their applications efficiently.</p>
<p><em>By leveraging Zustand's simplicity, performance optimizations, flexibility, and developer-friendly features, developers can create efficient and maintainable React applications with a smooth state management experience.</em>  </p>
<p>Learn more about Zustand: <a target="_blank" href="https://github.com/pmndrs/zustand">https://github.com/pmndrs/zustand</a></p>
<p>Follow Me and Let's Keep the Fun Rolling! If You Enjoyed the Read, Hit that Follow Button and Join the Hilarity! :)</p>
]]></content:encoded></item><item><title><![CDATA[Journey Through Time: Exploring the Evolution of Frontend Development]]></title><description><![CDATA[Welcome aboard as we embark on a fascinating journey through the ever-evolving world of frontend development. Buckle up and get ready to travel back in time to witness the remarkable transformation from static HTML pages to the dynamic and immersive ...]]></description><link>https://blog.hemant.lol/evolution-of-frontend-development</link><guid isPermaLink="true">https://blog.hemant.lol/evolution-of-frontend-development</guid><category><![CDATA[Frontend Development]]></category><category><![CDATA[Static Website]]></category><category><![CDATA[PWA]]></category><dc:creator><![CDATA[Hemant]]></dc:creator><pubDate>Wed, 24 May 2023 11:35:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1684927917347/e461a319-c39e-4589-b603-3a6d5aae4c4e.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome aboard as we embark on a fascinating journey through the ever-evolving world of frontend development. Buckle up and get ready to travel back in time to witness the remarkable transformation from static HTML pages to the dynamic and immersive web experiences we enjoy today. Prepare to be captivated by the tales of groundbreaking technologies, design trends, and the relentless pursuit of seamless user experiences across devices. Let's dive in!</p>
<h1 id="heading-1-the-dawn-of-frontend-a-glimpse-into-static-html">1. The Dawn of Frontend: A Glimpse into Static HTML</h1>
<p>Close your eyes and imagine the early days of the web. Picture a world of static HTML pages, where content reigned supreme. Developers harnessed the power of HTML tags to structure information, while basic CSS styles added a touch of visual appeal. It was a simple yet pivotal era that laid the foundation for what was to come.</p>
<h1 id="heading-2-unleashing-the-power-of-interactivity-enter-javascript">2. Unleashing the Power of Interactivity: Enter JavaScript</h1>
<p>In this chapter, we witness the emergence of JavaScript, the dynamic force that breathed life into static web pages. JavaScript's arrival introduced a new realm of possibilities, allowing developers to create engaging experiences through animations, form validations, and interactive menus. The web was no longer a static landscape—it became a playground for creativity.</p>
<h1 id="heading-3-css-the-art-of-style-and-presentation">3. CSS: The Art of Style and Presentation</h1>
<p>As the web continued to evolve, developers sought better ways to control the visual aesthetics of websites. The introduction of CSS brought forth a revolution. By separating content from presentation, frontend developers gained the ability to define styles, layouts, and positioning. This newfound power transformed websites into visually stunning works of art.</p>
<h1 id="heading-4-taming-the-wild-west-web-standards-and-cross-browser-compatibility">4. Taming the Wild West: Web Standards and Cross-Browser Compatibility</h1>
<p>Picture the frontier of the web, where different browsers roamed freely, each with its own interpretation of HTML and CSS. This chapter focuses on the rise of web standards and the quest for cross-browser compatibility. With the development of the Document Object Model (DOM) and W3C recommendations, developers embarked on a mission to unify the web, ensuring consistent experiences for users regardless of their browser of choice.</p>
<h1 id="heading-5-from-chaos-to-order-the-rise-of-css-frameworks">5. From Chaos to Order: The Rise of CSS Frameworks</h1>
<p>In this chapter, we witness the dawn of CSS frameworks, heralding an era of efficiency and consistency in frontend development. Frameworks like Bootstrap and Foundation provided developers with pre-designed components, responsive grids, and a standardized approach to building websites. With these powerful tools at their disposal, developers could rapidly create stunning interfaces while maintaining consistency across projects.</p>
<h1 id="heading-6-the-javascript-renaissance-enter-the-world-of-frameworks">6. The JavaScript Renaissance: Enter the World of Frameworks</h1>
<p>Prepare to be amazed as we delve into the golden age of JavaScript frameworks. AngularJS, React, and Vue.js take center stage, introducing us to component-based architecture, virtual DOM manipulation, and reactive data binding. These frameworks empower developers to build complex, interactive web applications with ease, revolutionizing the frontend landscape.</p>
<h1 id="heading-7-embracing-the-mobile-revolution-mobile-first-design-and-responsive-web">7. Embracing the Mobile Revolution: Mobile-First Design and Responsive Web</h1>
<p>As smartphones and mobile devices became ubiquitous, a paradigm shift occurred in frontend development. Mobile-first design took the stage, placing emphasis on optimizing websites for mobile devices before scaling up for larger screens. Responsive web design techniques, such as fluid grids and media queries, became crucial for delivering seamless experiences across a multitude of devices.</p>
<h1 id="heading-8-performance-matters-unlocking-the-power-of-optimization">8. Performance Matters: Unlocking the Power of Optimization</h1>
<p>Speed and performance optimization take the spotlight in this chapter. Discover the techniques employed by frontend developers to ensure lightning-fast page load times. From minification and caching to lazy loading and asynchronous scripts, these optimizations enhance user experiences and keep visitors engaged in our fast-paced digital world.</p>
<h1 id="heading-9-the-rise-of-progressive-web-apps-pwas">9. The Rise of Progressive Web Apps (PWAs)</h1>
<p>Enter the age of Progressive Web Apps (PWAs), where the web meets the power of native applications. Explore how PWAs combine the best of both worlds, offering offline functionality, push notifications, and the ability to be installed on the user's home screen. This groundbreaking technology paves the way for immersive, app-like experiences on the web.</p>
<h1 id="heading-conclusion">Conclusion:</h1>
<p>As we conclude this captivating exploration of the evolution of frontend development, we hope you've gained a deeper appreciation for the journey that has shaped the web as we know it today. From the humble beginnings of static HTML to the immersive experiences of mobile-first design and performance optimization, frontend development has evolved in remarkable ways.</p>
<p>If you enjoyed this blog and want to stay updated on the latest trends and insights in frontend development, we invite you to follow us on Hashnode. Join our community of passionate developers, share your thoughts, and engage in discussions about the ever-changing world of frontend development. Together, let's continue to push the boundaries of what's possible in creating exceptional user experiences on the web.</p>
<p>Safe travels on your own frontend development journey, and looking forward to connecting with you on Hashnode!</p>
<p>Follow me on Hashnode: <a target="_blank" href="https://hashnode.com/@hemantwasthere">https://hashnode.com/@hemantwasthere</a></p>
]]></content:encoded></item><item><title><![CDATA[Best practices for frontend development]]></title><description><![CDATA[Frontend development is a crucial part of building a web application or website. It involves creating the user interface (UI) and user experience (UX) of a website. A well-designed frontend can make or break the success of a website. In this blog, we...]]></description><link>https://blog.hemant.lol/best-practices-for-frontend-development</link><guid isPermaLink="true">https://blog.hemant.lol/best-practices-for-frontend-development</guid><category><![CDATA[WeMakeDevs]]></category><category><![CDATA[Hashnode]]></category><dc:creator><![CDATA[Hemant]]></dc:creator><pubDate>Sun, 14 May 2023 17:58:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1684087023797/40d45c1a-49ab-466d-a6b2-d4633b34c643.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Frontend development is a crucial part of building a web application or website. It involves creating the user interface (UI) and user experience (UX) of a website. A well-designed frontend can make or break the success of a website. In this blog, we will discuss some of the best practices that frontend developers should follow to create a high-quality UI/UX.</p>
<h1 id="heading-1-use-a-framework">1. Use a Framework</h1>
<p>One of the most important aspects of frontend development is choosing a framework. Frameworks like React, Angular, and Vue.js provide a solid foundation for building responsive and efficient web applications. These frameworks offer a wide range of pre-built components and modules, allowing developers to save time and focus on the core functionality of the application.</p>
<h1 id="heading-2-keep-it-simple">2. Keep it Simple</h1>
<p>When designing a frontend, it's important to keep things simple. Avoid using too many design elements or complex animations that could slow down the page load time. Use a clean and minimalist design that is easy on the eyes and easy to navigate. Remember, less is often more in web design.</p>
<h1 id="heading-3-make-it-responsive">3. Make it Responsive</h1>
<p>In today's world, users access websites on a variety of devices, from desktop computers to smartphones and tablets. Therefore, it's crucial to design a responsive frontend that adapts to different screen sizes. Use responsive design techniques like flexible grids and media queries to ensure that your website looks great on all devices.</p>
<h1 id="heading-4-optimize-page-load-time">4. Optimize Page Load Time</h1>
<p>Page load time is a critical factor in user experience. Users expect websites to load quickly, and if they don't, they're likely to leave and never come back. As a frontend developer, it's your responsibility to optimize the website's performance by reducing image and file sizes, minifying code, and leveraging browser caching.</p>
<h1 id="heading-5-use-consistent-design-patterns">5. Use Consistent Design Patterns</h1>
<p>Using consistent design patterns throughout the website helps to create a cohesive user experience. This means using the same color scheme, typography, and layout throughout the website. Consistency makes it easier for users to navigate the website and find what they're looking for.</p>
<h1 id="heading-6-test-across-multiple-browsers">6. Test Across Multiple Browsers</h1>
<p>Different browsers have different rendering engines, which means that a website might look different in different browsers. To ensure that your website looks great across all browsers, it's important to test it thoroughly using a range of browsers, including Chrome, Firefox, Safari, and Internet Explorer.</p>
<h1 id="heading-7-accessibility">7. Accessibility</h1>
<p>Web accessibility is the practice of making websites accessible to everyone, regardless of their physical abilities. As a frontend developer, you should ensure that your website is accessible by using semantic HTML tags, alt text for images, and providing captions for videos.</p>
<h1 id="heading-8-consistent-naming-conventions">8. Consistent naming conventions</h1>
<p>Consistent naming conventions are an important aspect of writing readable and maintainable code. When naming variables, functions, and classes, it is important to choose names that clearly describe their purpose and functionality. Using meaningful and descriptive names makes it easier for other developers to understand the code and reduces the likelihood of confusion or mistakes.</p>
<p>Here are some best practices for naming conventions:</p>
<ol>
<li><p>Use descriptive names that accurately reflect the purpose and functionality of the variable, function, or class.</p>
</li>
<li><p>Avoid abbreviations or acronyms that may not be clear to others. If you do use them, make sure they are well-known and commonly used.</p>
</li>
<li><p>Use camelCase for variable and function names (e.g. myVariable, myFunction).</p>
</li>
<li><p>Use PascalCase for class names (e.g. MyClass).</p>
</li>
<li><p>Use all caps with underscores for constants (e.g. MY_CONSTANT).</p>
</li>
<li><p>Use verbs for function names and nouns for variable and class names.</p>
</li>
<li><p>Use singular names for variables and classes, and plural names for arrays or collections.</p>
</li>
<li><p>Be consistent with your naming conventions throughout your codebase.</p>
</li>
</ol>
<h1 id="heading-9-organize-code-into-reusable-components">9. Organize Code into Reusable Components</h1>
<p>Yes, organizing code into reusable components is a fundamental principle of frontend development. It allows developers to create modular and scalable code, reducing the need for duplication and making it easier to maintain and update the codebase.</p>
<p>React and Angular are both popular JavaScript frameworks that enable developers to create reusable components easily. React components are based on a declarative programming model, making it easy to build complex UIs by breaking them down into smaller, reusable components. Angular components, on the other hand, provide an encapsulated view of a part of the UI, allowing developers to create reusable components that can be easily composed to build complex UIs.</p>
<p>Breaking code down into reusable components also promotes code consistency and reusability across different projects. For example, if you have created a component that displays a user profile in one project, you can reuse the same component in other projects where you need to display user profiles. This reduces the amount of time and effort required to develop new components from scratch, making development faster and more efficient.</p>
<p>In summary, organizing code into reusable components is a best practice in frontend development that promotes modularity, scalability, and reusability. Tools like React and Angular make it easy to create reusable components that can be used across projects, reducing development time and effort and promoting code consistency.</p>
<h1 id="heading-10-use-a-code-linter">10. Use a Code Linter</h1>
<p>Using a code linter is an essential best practice in frontend development. A code linter is a tool that scans your code and detects any errors or issues that may cause problems in the future. It enforces coding standards, promotes consistency, and helps identify potential problems early on in the development process.</p>
<p>ESLint and JSLint are two popular code linters used in frontend development. ESLint is a highly configurable linter that is widely used in the JavaScript community. It can be customized to enforce coding standards specific to your project, and it supports a wide range of plugins and rules to catch errors and promote best practices. JSLint, on the other hand, is a more rigid linter that enforces a strict set of coding standards. It can be useful for developers who want to ensure that their code follows a specific set of guidelines.</p>
<p>Using a code linter helps maintain the quality of your code by catching potential errors before they become a problem. It also promotes consistency by enforcing coding standards and highlighting any deviations from those standards. Additionally, using a linter can improve collaboration among team members by ensuring that all code follows the same standards and is easier to understand and maintain.</p>
<p>In summary, using a code linter like ESLint or JSLint is an essential best practice in frontend development. It helps catch potential errors early on, promotes consistency, and ensures that code is easier to understand and maintain.</p>
<h1 id="heading-11-test-your-code">11. Test Your Code</h1>
<p>Test your code thoroughly to ensure it works as expected and is free of bugs. Use tools like Jest or Mocha to create automated tests and run them regularly.</p>
<p>Jest and Mocha are two popular testing frameworks used in frontend development. Jest is a testing framework built on top of the Jasmine testing library. It provides a simple and intuitive testing experience, with features like snapshot testing, mock functions, and code coverage analysis. Mocha, on the other hand, is a more flexible testing framework that can be used with any assertion library. It allows developers to write tests in a variety of styles, including BDD (Behavior-Driven Development) and TDD (Test-Driven Development).</p>
<p>Automated testing is an essential component of testing in frontend development. Automated tests can be run regularly, providing rapid feedback on any changes made to the codebase. This helps catch potential problems early on and ensures that changes do not introduce new bugs or issues.</p>
<p>In summary, testing your code is a best practice in frontend development. It helps ensure that your code works as expected, is free of bugs, and performs well under various conditions. Jest and Mocha are popular testing frameworks that can be used to create automated tests. Automated testing provides rapid feedback on changes made to the codebase, helping catch potential problems early on in the development process.</p>
<h1 id="heading-12-document-your-code">12. Document your code</h1>
<p>Documenting your code is an important best practice in frontend development. Code documentation provides information about the purpose, functionality, and usage of different parts of the codebase, making it easier for other developers to understand and use your code. It can also help developers maintain and update the code more easily.</p>
<p>JSDoc is a popular tool used for documenting JavaScript code. It allows developers to create documentation comments directly in their code, using a specific syntax to describe the purpose and functionality of different parts of the code. JSDoc can be used to document functions, classes, variables, and other code elements, and it supports a wide range of tags for specifying parameters, return values, and other details.</p>
<p>Generating documentation from code comments can help save time and effort in the development process. It ensures that documentation stays up-to-date with the code and reduces the amount of time required to write and maintain documentation separately.</p>
<p>In summary, documenting your code is an essential best practice in frontend development. It helps other developers understand and use your code more easily and can also help with maintenance and updates. JSDoc is a useful tool for creating documentation comments in JavaScript code, and generating documentation from code comments can help save time and effort in the development process.</p>
]]></content:encoded></item><item><title><![CDATA[My Experience as a Professional Frontend Developer]]></title><description><![CDATA[As a professional frontend developer, I've had the opportunity to work on exciting projects and collaborate with talented designers, developers, and project managers. In this blog post, I'll share my experience as a frontend developer, tips for succe...]]></description><link>https://blog.hemant.lol/my-experience-as-a-professional-frontend-developer</link><guid isPermaLink="true">https://blog.hemant.lol/my-experience-as-a-professional-frontend-developer</guid><category><![CDATA[WeMakeDevs]]></category><dc:creator><![CDATA[Hemant]]></dc:creator><pubDate>Mon, 08 May 2023 17:17:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1683565663576/7b5b5158-c7de-442b-b788-c221b74de8ed.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As a professional frontend developer, I've had the opportunity to work on exciting projects and collaborate with talented designers, developers, and project managers. In this blog post, I'll share my experience as a frontend developer, tips for success, and advice for beginners and professionals.</p>
<h1 id="heading-frontend-development-a-brief-overview">Frontend Development: A Brief Overview</h1>
<p>Frontend development refers to the part of web development that deals with the user interface and user experience of a website or application. Frontend developers use languages like HTML, CSS, and JavaScript to create visually appealing and functional websites.</p>
<h1 id="heading-my-experience-as-a-frontend-developer">My Experience as a Frontend Developer</h1>
<p>I started my frontend development journey by learning HTML and CSS. After gaining some experience, I moved on to JavaScript, which allowed me to create dynamic and interactive websites. As I gained more experience, I became familiar with various frontend frameworks and libraries like React, and Vue.</p>
<p>One of the most significant challenges I faced as a frontend developer was ensuring that the websites I developed were responsive and worked well on different devices. To overcome this challenge, I had to learn about responsive design and develop my skills in CSS and JavaScript.</p>
<h1 id="heading-tips-for-success">Tips for Success</h1>
<ol>
<li><p>Learn the Basics: As a beginner frontend developer, it's essential to learn the basics of HTML, CSS, and JavaScript. These languages are the building blocks of frontend development, and you need to have a solid foundation in them.</p>
</li>
<li><p>Practice: Practice is essential to becoming a successful frontend developer. Take on challenging projects, experiment with different technologies, and build a portfolio of your work.</p>
</li>
<li><p>Master Frontend Frameworks: Frontend frameworks and libraries, such as React, Angular, and Vue.js, are becoming increasingly popular. As an experienced frontend developer, it's essential to master these frameworks or libraries to stay competitive in the job market. Choose a framework or library that suits your needs and learn it thoroughly.</p>
</li>
<li><p>Stay Current: Frontend development is a constantly evolving field, and it's essential to stay current with the latest trends and technologies. Read blogs, attend webinars, and join online communities to stay up-to-date.</p>
</li>
<li><p>Collaborate: Frontend development is a collaborative process, and it's essential to be able to work effectively with designers, developers, and project managers. Learn to listen actively, ask questions, and provide clear explanations.</p>
</li>
</ol>
<h1 id="heading-strategies-for-professionals">Strategies for Professionals</h1>
<ol>
<li><p>Keep Up with Emerging Technologies: Frontend development is a fast-paced field, and new technologies are continually emerging. Stay up-to-date with the latest trends and technologies by attending conferences, reading blogs, and following experts in the field.</p>
</li>
<li><p>Focus on User Experience: User experience (UX) is critical in frontend development. As a professional frontend developer, focus on creating engaging, accessible, and easy-to-use interfaces that provide a seamless user experience.</p>
</li>
<li><p>Collaborate with Others: Frontend development is rarely a solo endeavor. Collaborate with designers, developers, project managers, and stakeholders to ensure that everyone is on the same page. Effective collaboration can lead to better outcomes, increased productivity, and improved project outcomes.</p>
</li>
</ol>
<h1 id="heading-conclusion">Conclusion</h1>
<p>Frontend development is an exciting and challenging field that requires a combination of technical skills and creativity. By learning the basics, practicing, staying current, and collaborating effectively, you can become a successful frontend developer. Whether you're a beginner or an experienced professional, I hope these tips and strategies will help you achieve your frontend development goals.</p>
<h1 id="heading-free-resources-for-learning-and-mastering-frontend-development">Free Resources for Learning and Mastering Frontend Development</h1>
<ol>
<li><p>W3Schools: W3Schools is a popular website that provides free tutorials on HTML, CSS, JavaScript, and many other web technologies. It's a great resource for beginners who are just starting to learn frontend development.</p>
</li>
<li><p>FreeCodeCamp: FreeCodeCamp is a non-profit organization that provides free online courses on web development, including frontend development. Their curriculum covers HTML, CSS, JavaScript, and several frontend frameworks like React and Angular.</p>
</li>
<li><p>Mozilla Developer Network: The Mozilla Developer Network is an excellent resource for frontend developers. It provides free documentation on web technologies like HTML, CSS, JavaScript, and many others. They also have a large collection of tutorials and code snippets.</p>
</li>
</ol>
<h3 id="heading-youtube-channels-for-further-learning">YouTube Channels for Further Learning</h3>
<ol>
<li><p>Traversy Media: Traversy Media is a popular YouTube channel that provides high-quality tutorials on web development, including frontend development. Their videos cover HTML, CSS, JavaScript, and many frontend frameworks and libraries.</p>
</li>
<li><p>The Net Ninja: The Net Ninja is another popular YouTube channel that provides tutorials on web development, including frontend development. Their videos cover HTML, CSS, JavaScript, and several frontend frameworks like React and Vue.js.</p>
</li>
<li><p>Academind: Academind is a YouTube channel that provides tutorials on web development, including frontend development. Their videos cover HTML, CSS, JavaScript, and several frontend frameworks like React and Angular.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Drag n Drop using react-beautiful-dnd]]></title><description><![CDATA[INTRODUCTION
Drag and drop is an essential user interface feature that allows users to intuitively interact with web applications. It enables users to move elements within the application or between different applications, making it easier to organiz...]]></description><link>https://blog.hemant.lol/drag-n-drop</link><guid isPermaLink="true">https://blog.hemant.lol/drag-n-drop</guid><category><![CDATA[Drag & Drop]]></category><category><![CDATA[react-beautiful-dnd ]]></category><category><![CDATA[real world]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Hemant]]></dc:creator><pubDate>Sat, 06 May 2023 09:46:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1683357392875/70567d31-912e-40d2-9565-d1e40082459a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-introduction"><strong>INTRODUCTION</strong></h1>
<p>Drag and drop is an essential user interface feature that allows users to intuitively interact with web applications. It enables users to move elements within the application or between different applications, making it easier to organize content, reorder items, and streamline workflows. As a result, drag and drop has become a fundamental feature of many web applications, ranging from file managers to task management tools.</p>
<p>One popular library that developers can use to implement drag-and-drop functionality in their React-based applications is <code>react-beautiful-dnd.</code> <strong>React-beautiful-dnd</strong> is a flexible and powerful library that provides a simple and intuitive API for developers to create drag-and-drop interfaces. It leverages modern web technologies such as <strong>HTML5</strong> drag and drop and <strong>requestAnimationFrame</strong> to provide a smooth and responsive experience for users.</p>
<p>In this blog post, we will explore the benefits of using <code>react-beautiful-dnd</code> for implementing drag-and-drop functionality in React applications. We will examine some real-world examples of how drag and drop can improve the user experience in web applications, and how <strong>react-beautiful-dnd</strong> simplifies the development process. We will also provide step-by-step instructions on how to use the library, as well as tips and best practices for optimizing <strong>performance</strong> and <strong>usability</strong>. Whether you are new to React or an experienced developer, this blog post will provide valuable insights and practical guidance for implementing drag and drop in your web applications using <strong>react-beautiful-dnd</strong>.</p>
<h1 id="heading-set-up-the-environment">Set up the environment</h1>
<p>If you already have a React project set up, you can skip to the next section. Otherwise, here's a step-by-step guide to creating a new React project:</p>
<ol>
<li><p>Open your terminal and navigate to the directory where you want to create your project.</p>
</li>
<li><p>Run the following command to create a new React project using Create React App:</p>
</li>
</ol>
<pre><code class="lang-powershell">npx create<span class="hljs-literal">-react</span><span class="hljs-literal">-app</span> your<span class="hljs-literal">-app</span><span class="hljs-literal">-name</span>
</code></pre>
<h1 id="heading-installing-react-beautiful-dnd">Installing react-beautiful-dnd</h1>
<p>To install <code>react-beautiful-dnd</code>, you can use either <code>npm</code> or <code>yarn</code>. Here are the steps to install using both:</p>
<p><strong>Using npm:</strong></p>
<ol>
<li><p>Open your terminal and navigate to the root directory of your React project.</p>
</li>
<li><p>Run the following command to install <code>react-beautiful-dnd</code> and its dependencies:</p>
<pre><code class="lang-powershell"> npm install react<span class="hljs-literal">-beautiful</span><span class="hljs-literal">-dnd</span>
</code></pre>
<p> This will install <code>react-beautiful-dnd</code> along with its required dependencies, including <code>react</code>, <code>react-dom</code>, and <code>prop-types</code>.</p>
</li>
</ol>
<p><strong>Using yarn:</strong></p>
<ol>
<li><p>Open your terminal and navigate to the root directory of your React project.</p>
</li>
<li><p>Run the following command to install <code>react-beautiful-dnd</code> and its dependencies:</p>
<pre><code class="lang-powershell"> yarn add react<span class="hljs-literal">-beautiful</span><span class="hljs-literal">-dnd</span>
</code></pre>
<p> This will install <code>react-beautiful-dnd</code> along with its required dependencies, including <code>react</code>, <code>react-dom</code>, and <code>prop-types</code>.  </p>
<p> <code>react-beautiful-dnd</code> is a library for creating beautiful, accessible drag-and-drop interfaces for your React applications. It provides a simple API for implementing drag-and-drop functionality with customizable behavior and styling. The library uses the <strong>HTML5</strong> drag-and-drop <strong>API</strong> and supports touch devices as well.</p>
<p> <code>react-beautiful-dnd</code> has two main components: <code>DragDropContext</code> and <code>Droppable</code>. <code>DragDropContext</code> is a higher-order component that wraps your entire app and provides the context for drag-and-drop interactions. <code>Droppable</code> is a component that defines a container that can receive draggable items.</p>
<p> In addition to these components, <code>react-beautiful-dnd</code> also provides <code>Draggable</code> and <code>Droppable</code> components, which you can use to create drag-and-drop interfaces with ease.</p>
</li>
</ol>
<h1 id="heading-creating-a-draggable-list">Creating a draggable list</h1>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { DragDropContext, Droppable, Draggable } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-beautiful-dnd'</span>;

<span class="hljs-keyword">const</span> initialItems = [
  { <span class="hljs-attr">id</span>: <span class="hljs-string">'1'</span>, <span class="hljs-attr">content</span>: <span class="hljs-string">'Item 1'</span> },
  { <span class="hljs-attr">id</span>: <span class="hljs-string">'2'</span>, <span class="hljs-attr">content</span>: <span class="hljs-string">'Item 2'</span> },
  { <span class="hljs-attr">id</span>: <span class="hljs-string">'3'</span>, <span class="hljs-attr">content</span>: <span class="hljs-string">'Item 3'</span> },
];

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> [items, setItems] = useState(initialItems);

  <span class="hljs-keyword">const</span> onDragEnd = <span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (!result.destination) <span class="hljs-keyword">return</span>;
    <span class="hljs-keyword">const</span> { source, destination } = result;
    <span class="hljs-keyword">const</span> newItems = [...items];
    <span class="hljs-keyword">const</span> [removed] = newItems.splice(source.index, <span class="hljs-number">1</span>);
    newItems.splice(destination.index, <span class="hljs-number">0</span>, removed);
    setItems(newItems);
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">DragDropContext</span> <span class="hljs-attr">onDragEnd</span>=<span class="hljs-string">{onDragEnd}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Droppable</span> <span class="hljs-attr">droppableId</span>=<span class="hljs-string">"items"</span>&gt;</span>
        {(provided) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> {<span class="hljs-attr">...provided.droppableProps</span>} <span class="hljs-attr">ref</span>=<span class="hljs-string">{provided.innerRef}</span>&gt;</span>
            {items.map((item, index) =&gt; (
              <span class="hljs-tag">&lt;<span class="hljs-name">Draggable</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span> <span class="hljs-attr">draggableId</span>=<span class="hljs-string">{item.id}</span> <span class="hljs-attr">index</span>=<span class="hljs-string">{index}</span>&gt;</span>
                {(provided) =&gt; (
                  <span class="hljs-tag">&lt;<span class="hljs-name">li</span>
                    <span class="hljs-attr">ref</span>=<span class="hljs-string">{provided.innerRef}</span>
                    {<span class="hljs-attr">...provided.draggableProps</span>}
                    {<span class="hljs-attr">...provided.dragHandleProps</span>}
                  &gt;</span>
                    {item.content}
                  <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
                )}
              <span class="hljs-tag">&lt;/<span class="hljs-name">Draggable</span>&gt;</span>
            ))}
            {provided.placeholder}
          <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
        )}
      <span class="hljs-tag">&lt;/<span class="hljs-name">Droppable</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">DragDropContext</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>Let's break down each component and what it does:</p>
<ul>
<li><p><code>DragDropContext</code>: This is a higher-order component that wraps your entire app and provides the context for drag-and-drop interactions. It takes a <code>onDragEnd</code> prop, which is a callback function that is called when a drag-and-drop operation ends.</p>
</li>
<li><p><code>Droppable</code>: This is a component that defines a container that can receive draggable items. It takes a <code>droppableId</code> prop, which is a unique identifier for the droppable area, and a <code>children</code> function that takes an object with properties <code>provided</code> and <code>snapshot</code>. <code>provided</code> contains props that need to be applied to the droppable element, and <code>snapshot</code> contains information about the current state of the droppable area.</p>
</li>
<li><p><code>Draggable</code>: This is a component that defines a draggable item. It takes a <code>draggableId</code> prop, which is a unique identifier for the draggable item, and an <code>index</code> prop, which is the position of the item in the list. <code>children</code> the function takes an object with properties <code>provided</code> and <code>snapshot</code>. <code>provided</code> contains props that need to be applied to the draggable element, and <code>snapshot</code> contains information about the current state of the draggable item.</p>
</li>
</ul>
<p>In this example, we're using <code>useState</code> to manage the state of the list items. We're also defining a <code>onDragEnd</code> callback function that updates the state of the items when a drag-and-drop operation ends.</p>
<p>Inside the <code>Droppable</code> component, we're mapping over the <code>items</code> state and rendering a <code>Draggable</code> component for each item. The <code>Draggable</code> component is responsible for rendering the item and providing the necessary props for dragging and dropping.</p>
<p>Finally, we're using <code>provided.placeholder</code> to render a placeholder element while the item is being dragged. This is important for maintaining the layout of the list</p>
<h1 id="heading-add-styling">Add Styling</h1>
<p>One way is to add styles directly to the components using inline styles or className props. For example, you could add a className to the <code>li</code> element inside the <code>Draggable</code> component and then add styles for that class in your CSS:</p>
<p>First of all import <code>App.css</code> from the root directory in <code>App.js</code><br />After that imports should be like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { DragDropContext, Droppable, Draggable } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-beautiful-dnd'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;
</code></pre>
<p>Now go to <code>App.css</code> and add some styles to it, like this:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.item</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">rgb</span>(<span class="hljs-number">192</span>, <span class="hljs-number">122</span>, <span class="hljs-number">122</span>);
  <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#000000</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">4px</span>;
  <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">8px</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">8px</span>;
  <span class="hljs-attribute">list-style</span>: none;
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">30rem</span>;
}
</code></pre>
<p>After adding styles in your <code>App.css</code>, Add the <code>item</code> class to the list of item<code>(&lt;li&gt;)</code> which is displayed after mapping the items.</p>
<pre><code class="lang-javascript">&lt;Draggable key={item.id} draggableId={item.id} index={index}&gt;
  {<span class="hljs-function">(<span class="hljs-params">provided</span>) =&gt;</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{provided.innerRef}</span> {<span class="hljs-attr">...provided.draggableProps</span>} {<span class="hljs-attr">...provided.dragHandleProps</span>} <span class="hljs-attr">className</span>=<span class="hljs-string">'item'</span>&gt;</span>
    {item.content}
  <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span>
  )}
&lt;/Draggable&gt;
</code></pre>
<p>Then the output list should be looking like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1683363735084/7692f75f-86c7-4489-ae9e-907ec6340ba5.png" alt class="image--center mx-auto" /></p>
<p>Now if you are wondering if drag-n-drop is not working then go to the <code>index.js</code> in the root directory and disable the <code>React.StrictMode</code> after that, it will start working :)</p>
<pre><code class="lang-javascript">root.render(
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">React.StrictMode</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">React.StrictMode</span>&gt;</span></span>
);
</code></pre>
<p>After removing <code>React.StrictMode</code></p>
<pre><code class="lang-javascript">root.render(
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span>
);
</code></pre>
<p>Another way is to use the <code>provided</code> object that's passed to the <code>Droppable</code> and <code>Draggable</code> children functions. This object contains properties like <code>innerRef</code>, <code>draggableProps</code>, and <code>dragHandleProps</code> that you can use to style the components. For example:</p>
<pre><code class="lang-javascript">&lt;Draggable key={item.id} draggableId={item.id} index={index}&gt;
  {<span class="hljs-function">(<span class="hljs-params">provided, snapshot</span>) =&gt;</span> (
    <span class="hljs-comment">// Inside the Draggable component:</span>
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">li</span>
      <span class="hljs-attr">ref</span>=<span class="hljs-string">{provided.innerRef}</span>
      {<span class="hljs-attr">...provided.draggableProps</span>}
      {<span class="hljs-attr">...provided.dragHandleProps</span>}
      <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span>
        <span class="hljs-attr">backgroundColor:</span> <span class="hljs-attr">snapshot.isDragging</span> ? '<span class="hljs-attr">rgb</span>(<span class="hljs-attr">231</span>, <span class="hljs-attr">179</span>, <span class="hljs-attr">179</span>)' <span class="hljs-attr">:</span> '',
        <span class="hljs-attr">...provided.draggableProps.style</span>
      }}
      <span class="hljs-attr">className</span>=<span class="hljs-string">'item'</span>
    &gt;</span>
      {item.content}
    <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span>
  )}
&lt;/Draggable&gt;
</code></pre>
<p>In this example, we're using the <code>snapshot</code> object to check if the item is being dragged, and if so, we're changing the background color to a light gray. We're also using the <a target="_blank" href="http://provided.draggableProps.style"><code>provided.draggableProps.style</code></a> object to apply any additional styles that are required for the draggable item.</p>
<p>To make the list look visually appealing, you can add additional styles such as:</p>
<ul>
<li><p>A background color or gradient for the entire list.</p>
</li>
<li><p>A hover effect on the draggable items.</p>
</li>
<li><p>An animation or transition when the items are being dragged.</p>
</li>
<li><p>A border or shadow around the draggable items to give them a sense of depth.</p>
</li>
</ul>
<p>Overall, the styling you add will depend on the look and feel you want to achieve for your draggable list. Remember to keep it simple and clean, so that the drag-and-drop interactions remain clear and easy to use.</p>
<h1 id="heading-customize-the-behavior">Customize the behavior</h1>
<ol>
<li><p>Disable certain items from being dragged: To disable certain items from being dragged, you can add a <code>isDragDisabled</code> prop to the <code>Draggable</code> component. For example, if you want to disable the first item in the list from being dragged, you can do the following:</p>
<pre><code class="lang-javascript"> {items.map(<span class="hljs-function">(<span class="hljs-params">item, index</span>) =&gt;</span> (
   <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Draggable</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span> <span class="hljs-attr">draggableId</span>=<span class="hljs-string">{item.id}</span> <span class="hljs-attr">index</span>=<span class="hljs-string">{index}</span> <span class="hljs-attr">isDragDisabled</span>=<span class="hljs-string">{index</span> === <span class="hljs-string">0}</span>&gt;</span>
     {(provided, snapshot) =&gt; (
       // ...
     )}
   <span class="hljs-tag">&lt;/<span class="hljs-name">Draggable</span>&gt;</span></span>
 ))}
</code></pre>
<p> In this example, the <code>isDragDisabled</code> the prop is set to <code>true</code> for the first item in the list, so it cannot be dragged.</p>
</li>
<li><p>Disable dropping in certain places: To disable dropping in certain places, you can add a <code>isDropDisabled</code> prop to the <code>Droppable</code> component. For example, if you want to disable dropping items in the second list in a multi-column layout, you can do the following:</p>
<pre><code class="lang-javascript"> &lt;DragDropContext onDragEnd={onDragEnd}&gt;
   <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"columns"</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">Droppable</span> <span class="hljs-attr">droppableId</span>=<span class="hljs-string">"column-1"</span>&gt;</span>
       {(provided, snapshot) =&gt; (
         <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
           <span class="hljs-attr">ref</span>=<span class="hljs-string">{provided.innerRef}</span>
           <span class="hljs-attr">style</span>=<span class="hljs-string">{getListStyle(snapshot.isDraggingOver)}</span>
           {<span class="hljs-attr">...provided.droppableProps</span>}
           <span class="hljs-attr">isDropDisabled</span>=<span class="hljs-string">{true}</span> // <span class="hljs-attr">Add</span> <span class="hljs-attr">this</span> <span class="hljs-attr">prop</span> <span class="hljs-attr">to</span> <span class="hljs-attr">disable</span> <span class="hljs-attr">dropping</span> <span class="hljs-attr">in</span> <span class="hljs-attr">this</span> <span class="hljs-attr">list</span>
         &gt;</span>
           {items1.map((item, index) =&gt; (
             <span class="hljs-tag">&lt;<span class="hljs-name">Draggable</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span> <span class="hljs-attr">draggableId</span>=<span class="hljs-string">{item.id}</span> <span class="hljs-attr">index</span>=<span class="hljs-string">{index}</span>&gt;</span>
               {(provided, snapshot) =&gt; (
                 // ...
               )}
             <span class="hljs-tag">&lt;/<span class="hljs-name">Draggable</span>&gt;</span>
           ))}
           {provided.placeholder}
         <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
       )}
     <span class="hljs-tag">&lt;/<span class="hljs-name">Droppable</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">Droppable</span> <span class="hljs-attr">droppableId</span>=<span class="hljs-string">"column-2"</span>&gt;</span>
       {(provided, snapshot) =&gt; (
         <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
           <span class="hljs-attr">ref</span>=<span class="hljs-string">{provided.innerRef}</span>
           <span class="hljs-attr">style</span>=<span class="hljs-string">{getListStyle(snapshot.isDraggingOver)}</span>
           {<span class="hljs-attr">...provided.droppableProps</span>}
         &gt;</span>
           {items2.map((item, index) =&gt; (
             <span class="hljs-tag">&lt;<span class="hljs-name">Draggable</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span> <span class="hljs-attr">draggableId</span>=<span class="hljs-string">{item.id}</span> <span class="hljs-attr">index</span>=<span class="hljs-string">{index}</span>&gt;</span>
               {(provided, snapshot) =&gt; (
                 // ...
               )}
             <span class="hljs-tag">&lt;/<span class="hljs-name">Draggable</span>&gt;</span>
           ))}
           {provided.placeholder}
         <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
       )}
     <span class="hljs-tag">&lt;/<span class="hljs-name">Droppable</span>&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
 &lt;/DragDropContext&gt;
</code></pre>
<p> In this example, the <code>isDropDisabled</code> the prop is set to <code>true</code> for the second list, so items cannot be dropped into it.</p>
</li>
<li><p>Change the behavior on drag or drop: To change the behavior on drag or drop, you can use the <code>onDragStart</code>, <code>onDragUpdate</code>, <code>onDragEnd</code>, <code>onBeforeCapture</code>, <code>onBeforeDragStart</code>, and <code>onDragCancel</code> callbacks provided by the <code>DragDropContext</code> component. These callbacks receive an object containing information about the drag-and-drop operation, which you can use to modify the behavior as needed. For example, you could change the cursor or add a placeholder when an item is being dragged:</p>
</li>
</ol>
<pre><code class="lang-javascript">&lt;DragDropContext
  onDragStart={<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">document</span>.body.style.cursor = <span class="hljs-string">'grabbing'</span>;
  }}
  onDragEnd={<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> {
    <span class="hljs-built_in">document</span>.body.style.cursor = <span class="hljs-string">'auto'</span>;
    <span class="hljs-keyword">if</span> (result.destination) {
      <span class="hljs-comment">// Handle the drop</span>
    }
  }}
&gt;
  <span class="hljs-comment">// ...</span>
&lt;/DragDropContext&gt;
</code></pre>
<p>In this example, the <code>onDragStart</code> callback changes the cursor to a grabbing hand when an item is being dragged, and the</p>
<h1 id="heading-some-examples-of-how-the-drag-n-drop-can-be-used-in-real-world-scenarios">Some examples of how the drag-n-drop can be used in real-world scenarios</h1>
<p>Here are a few examples of how the drag-n-drop feature can be used in real-world scenarios:</p>
<ol>
<li><p>To-do list: A to-do list app can allow users to reorder their tasks by dragging and dropping them into a different order. For example, a user can prioritize their most important tasks by dragging them to the top of the list, or group similar tasks together by dragging them next to each other. The drag-and-drop feature can also be used to move tasks between different lists, such as a "To Do" list and a "Done" list.</p>
</li>
<li><p>File manager: A file manager app can allow users to organize their files by dragging and dropping them into different folders or rearranging them within a folder. For example, a user can group related files together by dragging them next to each other, or move a file to a different folder by dragging it to the appropriate folder icon. The drag-and-drop feature can also be used to copy or move files between different windows or applications.</p>
</li>
<li><p>E-commerce website: An e-commerce website can allow users to add items to their shopping cart by dragging and dropping them from a product grid or list. For example, a user can drag a product image to their shopping cart icon to add the item to their cart or drag the item to a specific area on the page to view more information or options for the product. The drag-and-drop feature can also be used to move items between the shopping cart and a wishlist or favorites list.</p>
</li>
<li><p>Kanban board: A Kanban board app can allow users to move tasks between different stages of a project by dragging and dropping them into the appropriate column. For example, a user can move a task from the "To Do" column to the "In Progress" column by dragging it to the appropriate column header or move a task to the "Done" column by dragging it to the bottom of the column. The drag-and-drop feature can also be used to reorder tasks within a column or move tasks to a different board or project.</p>
</li>
</ol>
<h1 id="heading-troubleshooting">Troubleshooting</h1>
<p>Here are some common issues that might arise when using react-beautiful-dnd, along with some troubleshooting tips:</p>
<ol>
<li><p>Droppable area not working: If the droppable area is not working, check that the droppable component is properly wrapped around the draggable components. Also, make sure that the droppableId is properly assigned to the droppable component and matches the draggableId assigned to the draggable components.</p>
</li>
<li><p>Dragged item not displaying properly: If the dragged item is not displaying properly, check that the draggable component has the proper styles assigned to it, such as position: absolute and z-index. Also, make sure that the onDragStart and onDragEnd callbacks are properly implemented.</p>
</li>
<li><p>Disabled draggable item is still draggable: If a disabled draggable item is still draggable, make sure that the isDragDisabled prop is properly assigned to the draggable component.</p>
</li>
<li><p>Scroll position jumping during drag: If the scroll position jumps during the drag, it might be because the scroll container is not properly sized. Make sure that the scroll container has a fixed height or is properly sized using CSS.</p>
</li>
<li><p>Incorrect index after reordering: If the index of an item is incorrect after reordering, it might be because the index is based on the order of the items in the original list. Make sure that the index is properly updated based on the new order of the items.</p>
</li>
</ol>
<p>For further learning, the react-beautiful-dnd documentation provides detailed troubleshooting guides and examples, along with an active community forum where users can ask questions and receive help from other users. Additionally, there are many online resources such as tutorials, videos, and blog posts that provide tips and best practices for using react-beautiful-dnd.  </p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In this blog, we've covered how to implement a drag-and-drop feature using the react-beautiful-dnd library. We've walked through the process of setting up a React project, installing react-beautiful-dnd, creating a draggable list using the <code>&lt;DragDropContext&gt;</code>, <code>&lt;Droppable&gt;</code>, and <code>&lt;Draggable&gt;</code> components, adding styling using <strong>CSS</strong> or a <strong>CSS preprocessor</strong>, and customizing the behavior of the drag-and-drop feature.</p>
<p>We've also provided examples of how the drag-and-drop feature can be used in real-world scenarios, such as reordering items in a to-do list or organizing files in a file manager. Additionally, we've provided some troubleshooting tips for common issues that might arise when using react-beautiful-dnd, along with resources for further learning.</p>
<p>Implementing a drag-and-drop feature can greatly enhance the user experience of your application, and react-beautiful-dnd provides a simple and flexible way to do so. We encourage readers to try implementing this feature using react-beautiful-dnd in their own projects and explore the many possibilities it offers for improving the usability and interactivity of their applications.</p>
<h1 id="heading-code-of-this-example">Code of this example</h1>
<ol>
<li><p><a target="_blank" href="https://github.com/hemantwasthere/drag-n-drop-blog-example">GitHub Repository</a></p>
</li>
<li><p>Follow me on <a target="_blank" href="https://twitter.com/hemantwasthere">Twitter</a></p>
</li>
</ol>
]]></content:encoded></item></channel></rss>