<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Usama Nazir</title>
    <description>The latest articles on Forem by Usama Nazir (@themrsami).</description>
    <link>https://forem.com/themrsami</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3441409%2F58bed0fe-ae77-4ac2-9fbc-695b20a81510.png</url>
      <title>Forem: Usama Nazir</title>
      <link>https://forem.com/themrsami</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/themrsami"/>
    <language>en</language>
    <item>
      <title>Convert Markdown to PDF Online - No Command Line Required</title>
      <dc:creator>Usama Nazir</dc:creator>
      <pubDate>Tue, 04 Nov 2025 19:54:13 +0000</pubDate>
      <link>https://forem.com/themrsami/convert-markdown-to-pdf-online-no-command-line-required-3570</link>
      <guid>https://forem.com/themrsami/convert-markdown-to-pdf-online-no-command-line-required-3570</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjaurgb6tbsmz3p8666y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjaurgb6tbsmz3p8666y.png" alt="An overview of the Landing Page" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Convert Markdown to PDF Online - No Command Line Required
&lt;/h1&gt;

&lt;p&gt;Have you ever struggled with converting Markdown files to PDF? Maybe you've tried Pandoc or other command-line tools, but they require installation, dependencies, and technical knowledge. What if I told you there's a better way?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Traditional Markdown to PDF Conversion
&lt;/h2&gt;

&lt;p&gt;Most developers face these issues:&lt;/p&gt;

&lt;p&gt;❌ &lt;strong&gt;Pandoc&lt;/strong&gt; - Requires installation, LaTeX dependencies, complex commands&lt;br&gt;&lt;br&gt;
❌ &lt;strong&gt;VS Code extensions&lt;/strong&gt; - Limited formatting options, no live preview&lt;br&gt;&lt;br&gt;
❌ &lt;strong&gt;GitHub/GitLab export&lt;/strong&gt; - Inconsistent styling, no customization&lt;br&gt;&lt;br&gt;
❌ &lt;strong&gt;Online tools&lt;/strong&gt; - Break on images, tables, or code blocks  &lt;/p&gt;
&lt;h2&gt;
  
  
  Introducing MarkdownToPDF.tech 🚀
&lt;/h2&gt;

&lt;p&gt;I built a &lt;strong&gt;free online Markdown to PDF converter&lt;/strong&gt; that solves all these problems. It works entirely in your browser - no installation, no command line, no sign-up required.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Try it now:&lt;/strong&gt; &lt;a href="https://www.markdowntopdf.tech" rel="noopener noreferrer"&gt;www.markdowntopdf.tech&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  ✨ Key Features
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. &lt;strong&gt;Real-Time Preview&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Write Markdown on the left, see the PDF preview on the right. Instantly.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. &lt;strong&gt;Full Markdown Support&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ Headers, bold, italic, strikethrough&lt;/li&gt;
&lt;li&gt;✅ Code blocks with syntax highlighting (190+ languages)&lt;/li&gt;
&lt;li&gt;✅ Tables with proper formatting&lt;/li&gt;
&lt;li&gt;✅ Images (local or URLs)&lt;/li&gt;
&lt;li&gt;✅ Task lists (&lt;code&gt;- [x]&lt;/code&gt; checkboxes)&lt;/li&gt;
&lt;li&gt;✅ Blockquotes and nested lists&lt;/li&gt;
&lt;li&gt;✅ Horizontal rules&lt;/li&gt;
&lt;li&gt;✅ Links and footnotes&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  3. &lt;strong&gt;Advanced Features&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🧮 &lt;strong&gt;Math equations&lt;/strong&gt; with KaTeX (&lt;code&gt;$E=mc^2$&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;🧪 &lt;strong&gt;Chemistry notation&lt;/strong&gt; with mhchem (&lt;code&gt;$\ce{H2O}$&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;💻 &lt;strong&gt;Syntax highlighting&lt;/strong&gt; for code blocks&lt;/li&gt;
&lt;li&gt;🎨 &lt;strong&gt;Custom fonts &amp;amp; sizing&lt;/strong&gt; (16px to 24px)&lt;/li&gt;
&lt;li&gt;📄 &lt;strong&gt;Professional typography&lt;/strong&gt; (serif, sans-serif, monospace)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  4. &lt;strong&gt;Perfect for ChatGPT Conversations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Copy ChatGPT responses in Markdown format and export them as beautiful PDFs. Perfect for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Saving coding tutorials&lt;/li&gt;
&lt;li&gt;Documenting technical discussions&lt;/li&gt;
&lt;li&gt;Archiving research conversations&lt;/li&gt;
&lt;li&gt;Creating study guides&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  📊 Real-World Use Cases
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. &lt;strong&gt;Documentation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Convert README files, technical docs, or API documentation to professional PDFs.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. &lt;strong&gt;Academic Papers&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Write papers with math equations, citations, and code examples.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. &lt;strong&gt;Meeting Notes&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Convert your Markdown notes from Obsidian, Notion, or any editor to PDF.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. &lt;strong&gt;Blog Posts&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Draft posts in Markdown, export to PDF for review or sharing.&lt;/p&gt;
&lt;h3&gt;
  
  
  5. &lt;strong&gt;Resumes &amp;amp; Reports&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Create professional documents with clean formatting.&lt;/p&gt;
&lt;h2&gt;
  
  
  💡 Why I Built This
&lt;/h2&gt;

&lt;p&gt;As a developer, I was frustrated with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installing Pandoc and managing LaTeX dependencies&lt;/li&gt;
&lt;li&gt;Running complex command-line scripts&lt;/li&gt;
&lt;li&gt;Dealing with broken formatting in online converters&lt;/li&gt;
&lt;li&gt;No live preview while editing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted a tool that &lt;strong&gt;just works&lt;/strong&gt; - paste Markdown, get a beautiful PDF. No friction.&lt;/p&gt;
&lt;h2&gt;
  
  
  🛠️ Technical Stack
&lt;/h2&gt;

&lt;p&gt;For the curious developers out there:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Next.js 14 with TypeScript&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Markdown Parser:&lt;/strong&gt; Custom parser (now available as &lt;a href="https://www.npmjs.com/package/advanced-markdown" rel="noopener noreferrer"&gt;advanced-markdown&lt;/a&gt; npm package!)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Math Rendering:&lt;/strong&gt; KaTeX with mhchem extension&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Syntax Highlighting:&lt;/strong&gt; highlight.js (190+ languages)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF Generation:&lt;/strong&gt; Browser print API (no server processing!)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Styling:&lt;/strong&gt; Tailwind CSS&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🎁 Open Source Package
&lt;/h2&gt;

&lt;p&gt;The Markdown parser is now available as an npm package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;advanced-markdown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;parse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;advanced-markdown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;markdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
# Hello World
Math: $E = mc^2$
Chemistry: $&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;ce{H2O}$
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;markdown&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Math equations (KaTeX)&lt;/li&gt;
&lt;li&gt;✅ Chemistry notation (mhchem)&lt;/li&gt;
&lt;li&gt;✅ Syntax highlighting&lt;/li&gt;
&lt;li&gt;✅ TypeScript support&lt;/li&gt;
&lt;li&gt;✅ ~12KB minzipped&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📦 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/themrsami/advanced-markdown" rel="noopener noreferrer"&gt;github.com/themrsami/advanced-markdown&lt;/a&gt;&lt;br&gt;&lt;br&gt;
📦 &lt;strong&gt;npm:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/advanced-markdown" rel="noopener noreferrer"&gt;npmjs.com/package/advanced-markdown&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🚀 Get Started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Visit &lt;a href="https://www.markdowntopdf.tech" rel="noopener noreferrer"&gt;markdowntopdf.tech&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Paste your Markdown content&lt;/li&gt;
&lt;li&gt;Click "Export" in the toolbar&lt;/li&gt;
&lt;li&gt;Download your PDF&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it! No account, no payment, no installation.&lt;/p&gt;
&lt;h2&gt;
  
  
  📝 Tips for Best Results
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Use Proper Markdown Syntax&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# H1 for main title&lt;/span&gt;
&lt;span class="gu"&gt;## H2 for sections&lt;/span&gt;
&lt;span class="gu"&gt;### H3 for subsections&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Code Blocks with Language&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;\&lt;/code&gt;&lt;code&gt;javascript&lt;br&gt;
const code = "Syntax highlighting works!";&lt;br&gt;
\&lt;/code&gt;&lt;code&gt;\&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Tables Need Headers&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;| Column 1 | Column 2 |
|----------|----------|
| Data 1   | Data 2   |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Math Equations&lt;/strong&gt;&lt;br&gt;
Inline: &lt;code&gt;$x^2 + y^2 = z^2$&lt;/code&gt;&lt;br&gt;&lt;br&gt;
Display: &lt;code&gt;$$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🎨 Customization Options
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Font Family:&lt;/strong&gt; Serif, Sans-Serif, Monospace&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Font Size:&lt;/strong&gt; 16px - 24px&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Typography:&lt;/strong&gt; Professional spacing and line height&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Themes:&lt;/strong&gt; Light/Dark mode (coming soon!)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🌟 What's Next?
&lt;/h2&gt;

&lt;p&gt;I'm actively working on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Custom CSS themes&lt;/li&gt;
&lt;li&gt;[ ] Template library (resume, paper, report)&lt;/li&gt;
&lt;li&gt;[ ] Batch conversion (multiple files)&lt;/li&gt;
&lt;li&gt;[ ] API for developers&lt;/li&gt;
&lt;li&gt;[ ] Browser extension&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  💬 Feedback Welcome!
&lt;/h2&gt;

&lt;p&gt;This tool is free and will always be free. If you find it useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐ Star the &lt;a href="https://github.com/themrsami/advanced-markdown" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐦 Share on Twitter/X&lt;/li&gt;
&lt;li&gt;💬 Leave feedback or feature requests&lt;/li&gt;
&lt;li&gt;🐛 Report bugs on GitHub&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔗 Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🌐 &lt;strong&gt;Web App:&lt;/strong&gt; &lt;a href="https://www.markdowntopdf.tech" rel="noopener noreferrer"&gt;markdowntopdf.tech&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📦 &lt;strong&gt;npm Package:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/advanced-markdown" rel="noopener noreferrer"&gt;advanced-markdown&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/themrsami/advanced-markdown" rel="noopener noreferrer"&gt;themrsami/advanced-markdown&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;👨‍💻 &lt;strong&gt;Author:&lt;/strong&gt; &lt;a href="https://github.com/themrsami" rel="noopener noreferrer"&gt;Usama Nazir&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Have you tried it yet?&lt;/strong&gt; What features would you like to see next? Drop a comment below! 👇&lt;/p&gt;

&lt;h1&gt;
  
  
  markdown #webdev #productivity #opensource #developer #tools
&lt;/h1&gt;

</description>
      <category>markdown</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>CSS Animations Tutorial: A Beginner's Guide</title>
      <dc:creator>Usama Nazir</dc:creator>
      <pubDate>Tue, 14 Oct 2025 04:47:33 +0000</pubDate>
      <link>https://forem.com/themrsami/css-animations-tutorial-a-beginners-guide-1e4j</link>
      <guid>https://forem.com/themrsami/css-animations-tutorial-a-beginners-guide-1e4j</guid>
      <description>&lt;p&gt;CSS animations can really help your website or brand pop by adding dynamic, eye-catching effects. If you're new to them, they might feel intimidating at first, but once you grasp the key properties, they're straightforward and fun to work with. This guide breaks down everything from the video, explaining the essential CSS animation properties step by step. We'll cover how to create animations, when to use them over transitions, and even how to make them interactive. Let's dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use Animations vs. Transitions
&lt;/h2&gt;

&lt;p&gt;Before jumping into animations, it's worth asking: Do I really need a full animation, or would a simple transition do the trick? &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Transitions&lt;/strong&gt; are ideal for straightforward changes from one state to another, like hovering over an element to alter its color, size, or position. They handle single-step shifts smoothly, no matter how many properties you're changing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Animations&lt;/strong&gt;, on the other hand, shine when you need a sequence of multiple steps or an ongoing, looping effect (e.g., something spinning in the background). The &lt;code&gt;animation&lt;/code&gt; property is a shorthand that combines several sub-properties to define these more complex behaviors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it's a one-and-done change, stick with transitions. For multi-step or continuous motion, animations are your go-to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Your First Animation with @keyframes
&lt;/h2&gt;

&lt;p&gt;To create an animation, start by defining it with the &lt;code&gt;@keyframes&lt;/code&gt; rule. This is where you outline the sequence of changes over time.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Name Your Animation&lt;/strong&gt;: Choose a descriptive name, like &lt;code&gt;spin&lt;/code&gt;. It's totally up to you—just make it memorable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Define the Sequence&lt;/strong&gt;: Use percentages to mark keyframes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;0%&lt;/code&gt;: The starting point.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;100%&lt;/code&gt;: The ending point.&lt;/li&gt;
&lt;li&gt;Anything in between (e.g., &lt;code&gt;50%&lt;/code&gt;): Intermediate steps.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, to spin an element 360 degrees and turn it into a circle by the end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;   &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;spin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="c"&gt;/* Initial state (implied if not specified) */&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Want to add complexity? At &lt;code&gt;50%&lt;/code&gt;, scale it up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;   &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;spin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="c"&gt;/* Starting point */&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c"&gt;/* Keep the scale for the full effect */&lt;/span&gt;
       &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key tip: If you're changing a property mid-animation (like scale), you must carry it forward to later keyframes if you want the change to persist. Otherwise, it'll revert smoothly to the next defined state.&lt;/p&gt;

&lt;p&gt;To separate growing from spinning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;   &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;spin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="c"&gt;/* Square and unrotated */&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSS will interpolate (blend) between keyframes automatically if something isn't specified, creating smooth transitions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying the Animation to an Element
&lt;/h2&gt;

&lt;p&gt;Once your keyframes are set, attach the animation to your HTML element (e.g., a &lt;code&gt;div&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;spin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c"&gt;/* How long the full cycle takes */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On page load, it'll run once and snap back to the start. Now, let's tweak it with more properties for control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fine-Tuning with Animation Properties
&lt;/h2&gt;

&lt;p&gt;These properties let you customize timing, speed, repetition, and more. They can all be shorthand-ed into one &lt;code&gt;animation&lt;/code&gt; line, but we'll break them down.&lt;/p&gt;

&lt;h3&gt;
  
  
  animation-duration
&lt;/h3&gt;

&lt;p&gt;Sets the length of one cycle. Shorter for quick effects, longer for deliberate ones.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;animation-duration: 0.5s;&lt;/code&gt; (fast) vs. &lt;code&gt;3s&lt;/code&gt; (slower).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  animation-timing-function
&lt;/h3&gt;

&lt;p&gt;Controls the speed curve, how the animation accelerates or decelerates.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Default: &lt;code&gt;ease&lt;/code&gt; (slows at each step for smoothness).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;linear&lt;/code&gt;: Constant speed throughout.&lt;/li&gt;
&lt;li&gt;Others: &lt;code&gt;ease-in&lt;/code&gt; (starts slow), &lt;code&gt;ease-out&lt;/code&gt; (ends slow), &lt;code&gt;ease-in-out&lt;/code&gt; (slow at both ends).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Easing makes things feel more natural, like in video editing.&lt;/p&gt;

&lt;h3&gt;
  
  
  animation-delay
&lt;/h3&gt;

&lt;p&gt;Pauses before starting.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;animation-delay: 1s;&lt;/code&gt; (waits 1 second).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  animation-iteration-count
&lt;/h3&gt;

&lt;p&gt;How many times it repeats.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Default: &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A number like &lt;code&gt;3&lt;/code&gt; for finite loops.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;infinite&lt;/code&gt; for endless playback (great for backgrounds).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  animation-direction
&lt;/h3&gt;

&lt;p&gt;Changes playback order.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Default: &lt;code&gt;normal&lt;/code&gt; (0% to 100%).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;reverse&lt;/code&gt;: Backwards (100% to 0%).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;alternate&lt;/code&gt;: Switches direction each cycle (forward, then reverse) for multi-iterations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  animation-fill-mode
&lt;/h3&gt;

&lt;p&gt;Decides what happens after the animation ends.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Without it: Snaps back to initial state.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;forwards&lt;/code&gt;: Holds the final keyframe's styles (e.g., stays as a circle).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives animations a permanent impact.&lt;/p&gt;

&lt;h3&gt;
  
  
  animation-play-state
&lt;/h3&gt;

&lt;p&gt;Makes animations interactive!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Default: &lt;code&gt;running&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set to &lt;code&gt;paused&lt;/code&gt; on events like &lt;code&gt;:hover&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="nc"&gt;.element&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;animation-play-state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or vice versa: Pause by default, run on hover.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;With JavaScript: Add buttons to toggle via &lt;code&gt;element.style.animationPlayState = 'paused'&lt;/code&gt; or &lt;code&gt;'running'&lt;/code&gt;. Simple click listeners create play/pause controls.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using the Animation Shorthand
&lt;/h2&gt;

&lt;p&gt;Combine everything in one property for cleaner code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;animation&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;spin&lt;/span&gt; &lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="nt"&gt;s&lt;/span&gt; &lt;span class="nt"&gt;ease&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;s&lt;/span&gt; &lt;span class="nt"&gt;infinite&lt;/span&gt; &lt;span class="nt"&gt;alternate&lt;/span&gt; &lt;span class="nt"&gt;forwards&lt;/span&gt; &lt;span class="nt"&gt;running&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Order: name, duration, timing-function, delay, iteration-count, direction, fill-mode, play-state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practice Exercise: Building a Loading Animation
&lt;/h2&gt;

&lt;p&gt;Let's apply this to a real example. A glowing square that rotates in 3D for a loading spinner.&lt;/p&gt;

&lt;p&gt;HTML:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;CSS Setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.loading&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c"&gt;/* Glow effect */&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-50%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;-50%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;loading&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;ease-in-out&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keyframes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotateZ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;33&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;180deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotateZ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;67&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;180deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;180deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotateZ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;180deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;180deg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rotateZ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;180deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It rotates on X, Y, then Z axes. Since 180° looks like 0°, the loop resets seamlessly without visible jumps.&lt;/p&gt;

&lt;p&gt;There you have it. A complete rundown on CSS animations. Experiment with these properties to bring your designs to life! If you're into web development, check out more tutorials for deeper dives.&lt;/p&gt;

</description>
      <category>css</category>
      <category>cssanimation</category>
      <category>animation</category>
      <category>html</category>
    </item>
    <item>
      <title>Getting Tailwind CSS Running in React and Next.js (Without the Headaches)</title>
      <dc:creator>Usama Nazir</dc:creator>
      <pubDate>Thu, 09 Oct 2025 04:21:57 +0000</pubDate>
      <link>https://forem.com/themrsami/getting-tailwind-css-running-in-react-and-nextjs-without-the-headaches-442h</link>
      <guid>https://forem.com/themrsami/getting-tailwind-css-running-in-react-and-nextjs-without-the-headaches-442h</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6lys3tqyo04hbqpsvyxh.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6lys3tqyo04hbqpsvyxh.webp" alt="A practical guide to setting up Tailwind CSS in modern React and Next.js projects" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A practical guide to setting up Tailwind CSS in modern React and Next.js projects, covering both version 3 and 4 installations, solving the dark mode implementation puzzle, and sharing real-world patterns that actually help you build faster.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The first time I tried Tailwind, I stared at someone's code with about fifteen class names on a single div and thought "this is madness." Two weeks later, I was building faster than I ever had with traditional CSS. Funny how that works.&lt;/p&gt;

&lt;p&gt;If you're setting up Tailwind for the first time, you'll probably hit the same confusing spots I did, especially around which version to use and how to make dark mode actually work. Let me save you some Googling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Tailwind Feels Weird at First
&lt;/h2&gt;

&lt;p&gt;Traditional CSS has you writing in separate files, coming up with clever class names, then wondering six months later what &lt;code&gt;.card-wrapper-container&lt;/code&gt; was supposed to mean. &lt;a href="https://tailwindcss.com/docs/utility-first" rel="noopener noreferrer"&gt;Tailwind flips this entirely&lt;/a&gt; by letting you compose styles directly in your markup using pre-built utility classes.&lt;/p&gt;

&lt;p&gt;Want padding? Add &lt;code&gt;p-4&lt;/code&gt;. Different padding on tablets? Use &lt;code&gt;md:p-6&lt;/code&gt;. Change text color? Try &lt;code&gt;text-slate-700&lt;/code&gt;. Your first reaction will be "wow, this looks messy." Push through that feeling for an afternoon of building something real. You'll notice you're staying in one mental context instead of jumping between files, and that speeds up everything.&lt;/p&gt;

&lt;p&gt;The clever bit happens during your build. Tailwind scans your entire codebase for class names and generates CSS containing only what you actually used. Despite having thousands of utilities available in &lt;a href="https://tailwindcss.com/docs/theme" rel="noopener noreferrer"&gt;Tailwind's system&lt;/a&gt;, your production bundle stays surprisingly lean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should You Use Version 3 or 4?
&lt;/h2&gt;

&lt;p&gt;Version 3 is what you'll find in most production codebases right now. It works great and isn't going anywhere soon. Version 4 launched late last year with a Rust-based engine that makes builds faster and simplifies setup by removing the PostCSS requirement in most cases.&lt;/p&gt;

&lt;p&gt;My advice? Use v3 if you're working on an existing project or collaborating with a team that hasn't upgraded yet. Choose v4 for new personal projects where you want the latest improvements. Both versions work nearly identically once installed, so switching later isn't painful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up in React with Vite
&lt;/h2&gt;

&lt;p&gt;I'll show you v4 since it's simpler. Start by creating your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create vite@latest my-app &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--template&lt;/span&gt; react-ts
&lt;span class="nb"&gt;cd &lt;/span&gt;my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Tailwind with its Vite plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;tailwindcss @tailwindcss/vite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The magic happens in your &lt;code&gt;vite.config.ts&lt;/code&gt; file. You're telling Vite to process Tailwind during the build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vite&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;react&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vitejs/plugin-react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;tailwindcss&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@tailwindcss/vite&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;react&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nf"&gt;tailwindcss&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;// This hooks Tailwind into Vite's build pipeline&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now update your &lt;code&gt;src/index.css&lt;/code&gt; file to just this single line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"tailwindcss"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's genuinely it for v4. No config file needed. The new engine automatically finds your component files and scans them. Start your dev server with &lt;code&gt;npm run dev&lt;/code&gt; and you can immediately use classes like &lt;code&gt;bg-blue-500&lt;/code&gt; or &lt;code&gt;rounded-lg&lt;/code&gt; in your components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next.js Setup
&lt;/h2&gt;

&lt;p&gt;Next.js works a bit differently because it has PostCSS built in already. Create your Next.js project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app@latest my-app &lt;span class="nt"&gt;--typescript&lt;/span&gt; &lt;span class="nt"&gt;--app&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Tailwind with its PostCSS plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;tailwindcss @tailwindcss/postcss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;postcss.config.mjs&lt;/code&gt; file in your project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@tailwindcss/postcss&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update your &lt;code&gt;app/globals.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"tailwindcss"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://nextjs.org/docs/app/building-your-application/styling/tailwind-css" rel="noopener noreferrer"&gt;Next.js documentation&lt;/a&gt; covers additional patterns, but this gets you running. The import in your root layout stays the same, and Tailwind automatically discovers your Next.js project structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making Dark Mode Actually Work
&lt;/h2&gt;

&lt;p&gt;Dark mode trips everyone up at first because you need to coordinate between Tailwind's CSS system and JavaScript that toggles classes. Here's the clearest path forward.&lt;/p&gt;

&lt;p&gt;First, tell Tailwind to watch for a &lt;code&gt;dark&lt;/code&gt; class. In your global CSS file (after the Tailwind import), add this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"tailwindcss"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;/* This tells Tailwind: apply dark: variants when a parent element has the dark class */&lt;/span&gt;
&lt;span class="k"&gt;@variant&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(.&lt;/span&gt;&lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dark&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now create a theme toggle component. This needs to manage three things: checking if the user has a saved preference, respecting their system preference if they don't, and updating both the DOM and localStorage when they toggle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ThemeToggle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTheme&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Check localStorage first&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;theme&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Fall back to system preference&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prefersDark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matchMedia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;(prefers-color-scheme: dark)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;saved&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prefersDark&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initial&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initial&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toggle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newTheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;setTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newTheme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Update the DOM immediately&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Save for next visit&lt;/span&gt;
    &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;theme&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newTheme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
      &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;toggle&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"p-2 rounded-lg bg-gray-200 dark:bg-gray-800"&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🌙&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;☀️&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's one annoying problem here. When someone visits your site with dark mode enabled, there's a brief flash of light mode before React loads and runs this code. The browser renders HTML before JavaScript executes.&lt;/p&gt;

&lt;p&gt;For Next.js projects, fix this by adding a tiny script that runs before React hydrates. Create a component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ThemeScript&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
    (function() {
      const theme = localStorage.getItem('theme');
      const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

      if (theme === 'dark' || (!theme &amp;amp;&amp;amp; prefersDark)) {
        document.documentElement.classList.add('dark');
      }
    })();
  `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Include it in your root layout's head:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ThemeScript&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./ThemeScript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;RootLayout&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ThemeScript&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can use &lt;a href="https://tailwindcss.com/docs/dark-mode" rel="noopener noreferrer"&gt;dark mode variants&lt;/a&gt; throughout your components like &lt;code&gt;bg-white dark:bg-slate-900&lt;/code&gt; or &lt;code&gt;text-gray-900 dark:text-gray-100&lt;/code&gt;, and they'll switch automatically when someone toggles the theme.&lt;/p&gt;

&lt;h2&gt;
  
  
  Patterns That Make Life Easier
&lt;/h2&gt;

&lt;p&gt;After building with Tailwind for a while, these practices consistently help.&lt;/p&gt;

&lt;p&gt;Install the &lt;a href="https://github.com/tailwindlabs/prettier-plugin-tailwindcss" rel="noopener noreferrer"&gt;Prettier plugin for Tailwind&lt;/a&gt;. It automatically sorts your classes in a consistent order, which stops git diffs from getting messy when everyone orders utilities differently.&lt;/p&gt;

&lt;p&gt;Grab the &lt;a href="https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss" rel="noopener noreferrer"&gt;Tailwind CSS IntelliSense extension&lt;/a&gt; for VS Code. It autocompletes class names, shows you the actual CSS on hover, and warns you about typos. This genuinely speeds up learning because you discover utilities without constantly checking docs.&lt;/p&gt;

&lt;p&gt;Keep your Tailwind config minimal. Only extend the theme when you need consistent custom values across many components. For one-off situations, &lt;a href="https://tailwindcss.com/docs/adding-custom-styles#using-arbitrary-values" rel="noopener noreferrer"&gt;arbitrary values&lt;/a&gt; like &lt;code&gt;bg-[#1a73e8]&lt;/code&gt; work fine. I've seen configs balloon to hundreds of lines that nobody remembers.&lt;/p&gt;

&lt;p&gt;Don't forget accessibility. Tailwind styles visual appearance but doesn't add semantic meaning. Always use proper HTML elements, test with keyboard navigation, and add ARIA attributes where needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Styles Aren't Working
&lt;/h2&gt;

&lt;p&gt;If you're seeing unstyled components, walk through this checklist. It catches most issues.&lt;/p&gt;

&lt;p&gt;First, verify your import. Make sure you're importing the CSS file in your app's entry point. In React with Vite, that's &lt;code&gt;src/main.tsx&lt;/code&gt;. In Next.js, it's your root layout.&lt;/p&gt;

&lt;p&gt;Second, for v3 setups, confirm PostCSS is configured correctly and the plugins are installed. Version 4 doesn't have this dependency, which is why I recommend it for new projects.&lt;/p&gt;

&lt;p&gt;Third, check for typos in class names. The IntelliSense extension helps enormously by underlining invalid classes.&lt;/p&gt;

&lt;p&gt;Fourth, clear your build cache and restart the dev server. Sometimes the build process gets stuck, especially after changing config files.&lt;/p&gt;

&lt;p&gt;One particularly frustrating bug happens when styles work in development but break in production. This usually means you're dynamically constructing class names like &lt;code&gt;text-${color}-500&lt;/code&gt;. Tailwind scans for complete strings during build. Either use complete class names or add them to the &lt;a href="https://tailwindcss.com/docs/content-configuration#safelisting-classes" rel="noopener noreferrer"&gt;safelist configuration&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to Learn More
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://tailwindcss.com/docs" rel="noopener noreferrer"&gt;official Tailwind documentation&lt;/a&gt; is genuinely excellent and searchable. Start there when you need to find specific utilities or understand configuration options.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tailwindui.com/" rel="noopener noreferrer"&gt;Tailwind UI&lt;/a&gt; is a commercial component library, but even the free examples teach you solid patterns for responsive design and component architecture. I learned a lot just by reading through their example code.&lt;/p&gt;

&lt;p&gt;Follow the &lt;a href="https://tailwindcss.com/blog" rel="noopener noreferrer"&gt;Tailwind Labs blog&lt;/a&gt; to stay current with v4 developments. The team writes clear explanatory posts about new features and design decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Learning Curve Is Worth It
&lt;/h2&gt;

&lt;p&gt;Tailwind changed how I build interfaces. The first few hours feel awkward because you're fighting muscle memory from traditional CSS. But once the utility-first approach clicks, you'll find yourself prototyping ideas much faster because you're staying in one mental context.&lt;/p&gt;

&lt;p&gt;Success with Tailwind isn't about memorizing classes. That's impossible. Instead, internalize the mental model of composing designs from small, purposeful utilities. Start with layout basics like flexbox and spacing. Gradually explore responsive variants and transitions. When you see a site you like, inspect it and learn from their patterns.&lt;/p&gt;

&lt;p&gt;Remember that Tailwind is a tool, not a religion. Write custom CSS when you need precise control. Use CSS modules for complex animations. Your goal is building excellent user experiences, and Tailwind is simply one way to get there faster.&lt;/p&gt;




&lt;h2&gt;
  
  
  About the Author
&lt;/h2&gt;

&lt;p&gt;I'm Usama Nazir, a full stack developer specializing in React, Next.js, and TypeScript. I write about modern web development patterns and share practical insights from real-world projects at &lt;a href="https://usama.codes" rel="noopener noreferrer"&gt;usama.codes&lt;/a&gt;. When I'm not building scalable web applications, I'm exploring new tools and helping other developers navigate the ever-evolving JavaScript ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;More from my blog:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://usama.codes/blog/sora-2-invite-code" rel="noopener noreferrer"&gt;Sora 2 Invite Code: How to Get Access to OpenAI Sora 2&lt;/a&gt; - A complete guide to accessing OpenAI's latest AI video generator&lt;/li&gt;
&lt;li&gt;Check out more articles on &lt;a href="https://usama.codes/blog" rel="noopener noreferrer"&gt;React, Next.js, and modern web development&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>javascript</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>Premium Responsive Navbar</title>
      <dc:creator>Usama Nazir</dc:creator>
      <pubDate>Mon, 18 Aug 2025 04:41:48 +0000</pubDate>
      <link>https://forem.com/themrsami/premium-responsive-navbar-45eo</link>
      <guid>https://forem.com/themrsami/premium-responsive-navbar-45eo</guid>
      <description>&lt;p&gt;Premium Look Navigation Bar for different purposes. added sections with ids. smooth animations. color changing animations. includes tailwindcss and google fonts. make sure you include tailwind and google fonts in your file.&lt;/p&gt;

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

</description>
      <category>codepen</category>
    </item>
  </channel>
</rss>
