<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Snappy Tools</title>
    <description>The latest articles on DEV Community by Snappy Tools (@snappy_tools).</description>
    <link>https://dev.to/snappy_tools</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%2F3863980%2F0cf60988-24da-462f-8d07-47fac7c5b263.png</url>
      <title>DEV Community: Snappy Tools</title>
      <link>https://dev.to/snappy_tools</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/snappy_tools"/>
    <language>en</language>
    <item>
      <title>Hash Functions Explained: MD5, SHA-1, SHA-256, and When to Use Each</title>
      <dc:creator>Snappy Tools</dc:creator>
      <pubDate>Sun, 07 Jun 2026 10:13:58 +0000</pubDate>
      <link>https://dev.to/snappy_tools/hash-functions-explained-md5-sha-1-sha-256-and-when-to-use-each-3d9p</link>
      <guid>https://dev.to/snappy_tools/hash-functions-explained-md5-sha-1-sha-256-and-when-to-use-each-3d9p</guid>
      <description>&lt;p&gt;Hash functions are one of those foundational computing concepts that show up everywhere — file integrity checks, password storage, digital signatures, API authentication, blockchain — but the choice of which hash to use is often made without understanding what actually differs between them.&lt;/p&gt;

&lt;p&gt;Let me explain the practical differences clearly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a Hash Function Does
&lt;/h2&gt;

&lt;p&gt;A hash function takes an input of any length and returns a fixed-length output (the "hash" or "digest"). The key properties:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic&lt;/strong&gt; — the same input always produces the same output&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One-way&lt;/strong&gt; — you cannot reverse the hash to recover the original input&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avalanche effect&lt;/strong&gt; — changing one character in the input completely changes the output&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collision resistant&lt;/strong&gt; — two different inputs should not produce the same hash (though collisions are mathematically possible)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The output length and collision resistance are what differ between algorithms.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Main Algorithms
&lt;/h2&gt;

&lt;h3&gt;
  
  
  MD5 (128-bit output, 32 hex characters)
&lt;/h3&gt;

&lt;p&gt;MD5 produces a 128-bit digest, displayed as 32 hex characters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;md5("hello") = 5d41402abc4b2a76b9719d911017c592
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Status: Cryptographically broken.&lt;/strong&gt; Collisions (two different inputs with the same hash) can be generated in seconds. MD5 is no longer suitable for any security-sensitive use case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Still used for:&lt;/strong&gt; Non-security checksums — verifying a file download wasn't corrupted in transit (corruption is accidental, not adversarial). Some legacy systems and database deduplication where collision attacks are not a concern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Never use for:&lt;/strong&gt; Password hashing, digital signatures, certificate fingerprinting, or any context where an attacker could craft a collision.&lt;/p&gt;

&lt;h3&gt;
  
  
  SHA-1 (160-bit output, 40 hex characters)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sha1("hello") = aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Status: Deprecated.&lt;/strong&gt; Google demonstrated a practical SHA-1 collision attack in 2017 ("SHAttered"). Most certificate authorities stopped issuing SHA-1 certificates years ago, and major browsers no longer accept them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Still used for:&lt;/strong&gt; Git commit hashes (Git uses SHA-1 internally for object IDs — collision resistance for Git's use case is sufficient but Git is slowly migrating to SHA-256). Legacy systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Never use for:&lt;/strong&gt; TLS certificates, code signing, password hashing, or anything security-critical.&lt;/p&gt;

&lt;h3&gt;
  
  
  SHA-256 (256-bit output, 64 hex characters)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sha256("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Status: Current standard. Use this for most things.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SHA-256 is part of the SHA-2 family and has no known practical vulnerabilities. It's used in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TLS certificates (HTTPS)&lt;/li&gt;
&lt;li&gt;Code signing&lt;/li&gt;
&lt;li&gt;JWT signatures (HS256, RS256)&lt;/li&gt;
&lt;li&gt;Bitcoin blockchain&lt;/li&gt;
&lt;li&gt;HMAC authentication (HMAC-SHA256)&lt;/li&gt;
&lt;li&gt;File integrity verification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to use it:&lt;/strong&gt; Any time you need a secure cryptographic hash for production use and don't have a specific reason to choose otherwise.&lt;/p&gt;

&lt;h3&gt;
  
  
  SHA-512 (512-bit output, 128 hex characters)
&lt;/h3&gt;

&lt;p&gt;SHA-512 produces a longer digest and is slightly faster than SHA-256 on 64-bit processors for large inputs, due to its 64-bit word operations. The practical difference in security is negligible for most applications — both are currently unbroken.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use when:&lt;/strong&gt; You need a longer digest for protocol compatibility, or you're hashing very large files and can benchmark a performance difference.&lt;/p&gt;

&lt;h3&gt;
  
  
  SHA-3 (variable output)
&lt;/h3&gt;

&lt;p&gt;SHA-3 (Keccak) is NIST's third-generation hash standard, with a fundamentally different internal structure from SHA-2. It's not faster than SHA-256 in most cases, but its different construction provides defence-in-depth if a theoretical attack on SHA-2's Merkle–Damgård structure were discovered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use when:&lt;/strong&gt; Your threat model specifically requires defence against SHA-2 structural attacks, or a protocol requires SHA-3.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Not to Use for Password Hashing
&lt;/h2&gt;

&lt;p&gt;None of the above algorithms — including SHA-256 — should be used directly for storing passwords. They're all too fast.&lt;/p&gt;

&lt;p&gt;An attacker with a GPU can compute billions of SHA-256 hashes per second, making dictionary and brute-force attacks trivial against a database of hashed passwords.&lt;/p&gt;

&lt;p&gt;Use purpose-built password hashing algorithms instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;bcrypt&lt;/strong&gt; — deliberately slow, work factor adjustable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Argon2&lt;/strong&gt; — NIST recommended, resistant to GPU attacks, won the Password Hashing Competition&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;scrypt&lt;/strong&gt; — memory-hard, makes GPU attacks expensive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These algorithms are specifically designed to be slow and computationally expensive, so brute-forcing a leaked password database takes years rather than hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Verification Example
&lt;/h2&gt;

&lt;p&gt;When you download software from the internet, many sites provide a SHA-256 hash of the file. After downloading, you verify it locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Linux / macOS&lt;/span&gt;
&lt;span class="nb"&gt;sha256sum &lt;/span&gt;downloaded-file.zip

&lt;span class="c"&gt;# macOS alternative&lt;/span&gt;
shasum &lt;span class="nt"&gt;-a&lt;/span&gt; 256 downloaded-file.zip

&lt;span class="c"&gt;# Windows PowerShell&lt;/span&gt;
Get-FileHash downloaded-file.zip &lt;span class="nt"&gt;-Algorithm&lt;/span&gt; SHA256
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the output matches the hash on the download page, the file arrived intact and unmodified.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Algorithm&lt;/th&gt;
&lt;th&gt;Output Length&lt;/th&gt;
&lt;th&gt;Security Status&lt;/th&gt;
&lt;th&gt;Use For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MD5&lt;/td&gt;
&lt;td&gt;32 hex chars&lt;/td&gt;
&lt;td&gt;Broken&lt;/td&gt;
&lt;td&gt;Non-security checksums only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SHA-1&lt;/td&gt;
&lt;td&gt;40 hex chars&lt;/td&gt;
&lt;td&gt;Deprecated&lt;/td&gt;
&lt;td&gt;Legacy only, avoid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SHA-256&lt;/td&gt;
&lt;td&gt;64 hex chars&lt;/td&gt;
&lt;td&gt;Secure&lt;/td&gt;
&lt;td&gt;General purpose — use this&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SHA-512&lt;/td&gt;
&lt;td&gt;128 hex chars&lt;/td&gt;
&lt;td&gt;Secure&lt;/td&gt;
&lt;td&gt;Large files, protocol-specific&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SHA-3&lt;/td&gt;
&lt;td&gt;Variable&lt;/td&gt;
&lt;td&gt;Secure&lt;/td&gt;
&lt;td&gt;Defence-in-depth, protocol-specific&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;Need to generate or verify a hash in the browser? The &lt;a href="https://snappytools.app/hash-generator/" rel="noopener noreferrer"&gt;Hash Generator&lt;/a&gt; supports MD5, SHA-1, SHA-256, SHA-384, and SHA-512 — runs entirely client-side, your input never leaves the browser. Useful for quick checksums and learning how different algorithms handle the same input.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tools</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Keyword Density in 2026: What the Numbers Actually Mean for SEO</title>
      <dc:creator>Snappy Tools</dc:creator>
      <pubDate>Sun, 07 Jun 2026 10:11:36 +0000</pubDate>
      <link>https://dev.to/snappy_tools/keyword-density-in-2026-what-the-numbers-actually-mean-for-seo-1lp8</link>
      <guid>https://dev.to/snappy_tools/keyword-density-in-2026-what-the-numbers-actually-mean-for-seo-1lp8</guid>
      <description>&lt;p&gt;Keyword density is one of those SEO concepts that's been declared dead, resurrected, and oversimplified dozens of times. The truth is somewhere more nuanced: density still matters — but not in the "hit 1–2% or Google won't rank you" way it was presented a decade ago.&lt;/p&gt;

&lt;p&gt;Here's what the numbers actually mean in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Formula (and Why It's Just a Starting Point)
&lt;/h2&gt;

&lt;p&gt;Keyword density is calculated as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Keyword Density (%) = (Keyword Count ÷ Total Word Count) × 100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A 1,000-word article with the keyword "keyword density" appearing 12 times has a density of 1.2%.&lt;/p&gt;

&lt;p&gt;That number is useful as a &lt;em&gt;diagnostic&lt;/em&gt;, not a target. It tells you whether a keyword is underused, appropriately used, or overused relative to the length of the text. What it can't tell you is whether Google will rank your page — that depends on relevance, authority, user intent, and dozens of other signals.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Ranges and What They Signal
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Density&lt;/th&gt;
&lt;th&gt;Classification&lt;/th&gt;
&lt;th&gt;What to do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;Missing&lt;/td&gt;
&lt;td&gt;Add the keyword naturally — at minimum in the title, intro, and a heading&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.1–0.5%&lt;/td&gt;
&lt;td&gt;Very low&lt;/td&gt;
&lt;td&gt;Fine for secondary keywords; may be too thin for a primary topic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.5–1%&lt;/td&gt;
&lt;td&gt;Low-normal&lt;/td&gt;
&lt;td&gt;Good for supporting keywords and related terms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1–2%&lt;/td&gt;
&lt;td&gt;Target range&lt;/td&gt;
&lt;td&gt;Natural, readable use of a primary keyword for most content types&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2–3%&lt;/td&gt;
&lt;td&gt;High but acceptable&lt;/td&gt;
&lt;td&gt;Common in shorter pieces where the keyword appears in headings and code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3–5%&lt;/td&gt;
&lt;td&gt;Borderline&lt;/td&gt;
&lt;td&gt;Check if the text reads naturally; reduce if it feels forced&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5%+&lt;/td&gt;
&lt;td&gt;Over-optimised&lt;/td&gt;
&lt;td&gt;Likely keyword stuffing — replace repetitions with synonyms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These ranges describe typical patterns in well-optimised content. They're not thresholds that trigger rankings or penalties.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Google Actually Uses
&lt;/h2&gt;

&lt;p&gt;Google moved away from keyword density as a primary ranking signal years ago. The current approach is more sophisticated:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TF-IDF&lt;/strong&gt; (Term Frequency–Inverse Document Frequency) normalises keyword frequency across the corpus — a word that appears everywhere is less meaningful than a word specific to your page. Google doesn't publish its TF-IDF implementation, but the principle guides how keyword importance is weighted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Semantic relevance&lt;/strong&gt; matters more than exact match. If you're writing about "coffee brewing methods", mentioning "pour over", "French press", "grind size", and "water temperature" signals topical coverage — even if your exact-match keyword count is lower than a competitor's.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User intent&lt;/strong&gt; is the frame that context must fit. A page targeting "how to brew coffee" needs step-by-step instructions; a page targeting "best coffee brewing equipment" needs product comparison. Forcing a high keyword density without matching user intent won't work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Density Still Matters Directly
&lt;/h2&gt;

&lt;p&gt;Despite the nuance above, there are three scenarios where density analysis remains directly useful:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Detecting keyword stuffing before publishing.&lt;/strong&gt; Running your draft through a density checker catches accidental over-optimisation — especially in short articles where a technical term might appear in every paragraph without you noticing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Diagnosing thin content.&lt;/strong&gt; If your primary keyword appears only once in a 2,000-word article, you probably haven't covered the topic with enough depth. Density below 0.3% on a primary keyword often indicates the article has drifted from its intended focus.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Checking multi-word phrases.&lt;/strong&gt; A bigram like "keyword density" might appear only twice (0.2%), while the individual words "keyword" and "density" each appear 15+ times. The phrase-level density check reveals whether you're targeting a specific phrase or just related individual words.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "How Many Times" Question
&lt;/h2&gt;

&lt;p&gt;People ask: "How many times should my keyword appear in a 1,000-word article?"&lt;/p&gt;

&lt;p&gt;If you want a number: 8–15 times for a primary keyword in a 1,000-word article puts you in the 0.8–1.5% range. That's a safe, readable zone for most content types.&lt;/p&gt;

&lt;p&gt;But the honest answer is: write naturally, check density afterward, and adjust if the number is wildly out of range. Inserting a keyword exactly 12 times because some guide said so produces awkward prose that users abandon early — which sends a stronger negative signal than keyword density ever could.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phrases, Not Just Words
&lt;/h2&gt;

&lt;p&gt;Most keyword density tools count single words by default. But your actual keyword target might be a two-word or three-word phrase.&lt;/p&gt;

&lt;p&gt;"Keyword density" and "keyword density checker" are different targets. A density check on the phrase "keyword density checker" will show a much lower number than checking "keyword density" alone — and that's the right number to look at when your page is targeting the three-word query.&lt;/p&gt;

&lt;p&gt;When checking density for phrases, always verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many times does the &lt;em&gt;exact phrase&lt;/em&gt; appear?&lt;/li&gt;
&lt;li&gt;How many times do the &lt;em&gt;component words&lt;/em&gt; appear independently?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both numbers are useful. A high individual-word density with low phrase density might mean you're covering the topic broadly but not targeting the specific query clearly enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools for Checking Density
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Yoast SEO&lt;/strong&gt; (WordPress) checks a single focus keyphrase you specify and gives a pass/fail indicator. Useful for quick checks during writing but limited to one keyword at a time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Semrush SEO Writing Assistant&lt;/strong&gt; shows density, readability, and originality in one panel. Requires a subscription.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free browser tools&lt;/strong&gt; like &lt;a href="https://snappytools.app/keyword-density-checker/" rel="noopener noreferrer"&gt;this keyword density checker&lt;/a&gt; analyse all word frequencies at once — useful for discovering which terms dominate your text before you decide what to optimise for. No account, no word limit, runs entirely in the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Practical Workflow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Write your content without thinking about density — focus on covering the topic thoroughly.&lt;/li&gt;
&lt;li&gt;Paste the draft into a density checker and scan the results.&lt;/li&gt;
&lt;li&gt;If your primary keyword is below 0.5%: add a few natural mentions in headings and key paragraphs.&lt;/li&gt;
&lt;li&gt;If your primary keyword is above 3%: read the flagged sentences aloud. Replace forced repetitions with synonyms or restructure the sentence.&lt;/li&gt;
&lt;li&gt;Check phrase-level density for your target two- or three-word query.&lt;/li&gt;
&lt;li&gt;Done. Move on.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Keyword density is a sanity check, not a score to maximise.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>beginners</category>
      <category>tools</category>
    </item>
    <item>
      <title>URL Encoding Explained: %20, + Signs, and the encodeURIComponent vs encodeURI Confusion</title>
      <dc:creator>Snappy Tools</dc:creator>
      <pubDate>Sun, 07 Jun 2026 10:11:35 +0000</pubDate>
      <link>https://dev.to/snappy_tools/url-encoding-explained-20-signs-and-the-encodeuricomponent-vs-encodeuri-confusion-1i0n</link>
      <guid>https://dev.to/snappy_tools/url-encoding-explained-20-signs-and-the-encodeuricomponent-vs-encodeuri-confusion-1i0n</guid>
      <description>&lt;p&gt;URL encoding trips up developers more often than it should. Not because it's complicated — it isn't — but because there are two different standards, multiple languages implement them slightly differently, and the difference between &lt;code&gt;%20&lt;/code&gt; and &lt;code&gt;+&lt;/code&gt; for a space has caused real production bugs.&lt;/p&gt;

&lt;p&gt;Let me break it down clearly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why URLs Need Encoding
&lt;/h2&gt;

&lt;p&gt;HTTP URLs can only safely contain a subset of ASCII characters: letters, digits, and a handful of symbols (&lt;code&gt;-._~:/?#[]@!$&amp;amp;'()*+,;=&lt;/code&gt;). Everything else — spaces, accented characters, &lt;code&gt;&amp;amp;&lt;/code&gt;, &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;#&lt;/code&gt;, and non-ASCII text — must be percent-encoded.&lt;/p&gt;

&lt;p&gt;Percent-encoding replaces the unsafe character with &lt;code&gt;%&lt;/code&gt; followed by the character's UTF-8 byte value in hexadecimal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Space → &lt;code&gt;%20&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;amp;&lt;/code&gt; → &lt;code&gt;%26&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;=&lt;/code&gt; → &lt;code&gt;%3D&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;é&lt;/code&gt; → &lt;code&gt;%C3%A9&lt;/code&gt; (two bytes in UTF-8)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple enough. The confusion starts when you need to choose &lt;em&gt;which kind&lt;/em&gt; of encoding to apply.&lt;/p&gt;

&lt;h2&gt;
  
  
  encodeURIComponent vs encodeURI: The Core Distinction
&lt;/h2&gt;

&lt;p&gt;JavaScript gives you two built-in functions, and mixing them up is the #1 URL encoding mistake:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;encodeURIComponent(value)&lt;/code&gt;&lt;/strong&gt; encodes &lt;em&gt;everything&lt;/em&gt; except: &lt;code&gt;A-Z a-z 0-9 - _ . ! ~ * ' ( )&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That includes &lt;code&gt;/&lt;/code&gt;, &lt;code&gt;?&lt;/code&gt;, &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;&amp;amp;&lt;/code&gt;, &lt;code&gt;#&lt;/code&gt;, &lt;code&gt;@&lt;/code&gt;, and &lt;code&gt;:&lt;/code&gt; — all URL structural characters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;encodeURI(url)&lt;/code&gt;&lt;/strong&gt; encodes everything &lt;em&gt;except&lt;/em&gt; URL structural characters: &lt;code&gt;: / ? # [ ] @ ! $ &amp;amp; ' ( ) * + , ; =&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The rule
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;encodeURIComponent&lt;/code&gt; for &lt;strong&gt;individual query parameter values&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;encodeURI&lt;/code&gt; for &lt;strong&gt;complete URLs&lt;/strong&gt; where you only want to encode unsafe characters without touching the URL's structure
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Correct — encoding a query value&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;coffee &amp;amp; cake&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://example.com/search?q=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// → https://example.com/search?q=coffee%20%26%20cake&lt;/span&gt;

&lt;span class="c1"&gt;// Wrong — encodeURI doesn't encode &amp;amp; so the parameter breaks&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://example.com/search?q=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;encodeURI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// → https://example.com/search?q=coffee%20&amp;amp;%20cake  ← broken!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The %20 vs + Space Confusion
&lt;/h2&gt;

&lt;p&gt;You'll see both &lt;code&gt;%20&lt;/code&gt; and &lt;code&gt;+&lt;/code&gt; used for spaces in URLs. They're not interchangeable:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Form&lt;/th&gt;
&lt;th&gt;Standard&lt;/th&gt;
&lt;th&gt;Valid In&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;RFC 3986 percent-encoding&lt;/td&gt;
&lt;td&gt;All URL contexts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;+&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTML form encoding (&lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Query strings only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;%20&lt;/code&gt; is always correct. &lt;code&gt;+&lt;/code&gt; is only correct in query strings when the server expects form-data encoding.&lt;/p&gt;

&lt;p&gt;This matters when you're encoding a redirect URL as a parameter — a &lt;code&gt;+&lt;/code&gt; inside a URL value that gets passed to another server and decoded as RFC 3986 will stay as a literal &lt;code&gt;+&lt;/code&gt;, not become a space.&lt;/p&gt;

&lt;h2&gt;
  
  
  Language Cheat Sheet
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;JavaScript / Node.js:&lt;/strong&gt;&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="c1"&gt;// Query parameter values&lt;/span&gt;
&lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello world &amp;amp; more&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// hello%20world%20%26%20more&lt;/span&gt;

&lt;span class="c1"&gt;// Query strings with URLSearchParams&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URLSearchParams&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;q&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;// q=hello+world (+ for spaces)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Python:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;urllib.parse&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urlencode&lt;/span&gt;

&lt;span class="nf"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello world &amp;amp; more&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;safe&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# hello%20world%20%26%20more
&lt;/span&gt;&lt;span class="nf"&gt;urlencode&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello world&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;        &lt;span class="c1"&gt;# q=hello+world (form encoding)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Java:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// URLEncoder uses + for spaces — this is form encoding, not RFC 3986&lt;/span&gt;
&lt;span class="nc"&gt;URLEncoder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;encode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello world"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;UTF_8&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// hello+world&lt;/span&gt;
&lt;span class="c1"&gt;// Replace + with %20 if you need RFC 3986:&lt;/span&gt;
&lt;span class="n"&gt;encoded&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;replace&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"+"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"%20"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;C#:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Use Uri.EscapeDataString — produces %20 for spaces (RFC 3986)&lt;/span&gt;
&lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EscapeDataString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello world &amp;amp; more"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// hello%20world%20%26%20more&lt;/span&gt;

&lt;span class="c1"&gt;// Avoid HttpUtility.UrlEncode — uses + for spaces&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;curl:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-G&lt;/span&gt; &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s2"&gt;"q=hello world &amp;amp; more"&lt;/span&gt; https://example.com/search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Double-Encoding: The Silent Bug
&lt;/h2&gt;

&lt;p&gt;If you encode an already-encoded string, the &lt;code&gt;%&lt;/code&gt; sign itself gets encoded to &lt;code&gt;%25&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;%20  (encoded space)
  ↓ encode again
%2520 (which decodes to "%20", not a space)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a common source of "double-encoded" URLs that confuse both users and servers. If your encoded string looks like &lt;code&gt;%2520&lt;/code&gt; instead of &lt;code&gt;%20&lt;/code&gt;, you have a double-encoding bug.&lt;/p&gt;

&lt;p&gt;Fix: always decode before re-encoding if the string might already be encoded.&lt;/p&gt;

&lt;h2&gt;
  
  
  When a URL Is a Parameter Value
&lt;/h2&gt;

&lt;p&gt;This is the trickiest case — a redirect URL embedded inside another URL:&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="c1"&gt;// Inner URL must be fully encoded so its ? &amp;amp; = / don't break the outer URL&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;innerUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://destination.com/path?key=value&amp;amp;other=data&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;outerUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://proxy.example.com/redirect?target=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;innerUrl&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// → https://proxy.example.com/redirect?target=https%3A%2F%2Fdestination.com%2Fpath%3Fkey%3Dvalue%26other%3Ddata&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only encode the &lt;em&gt;value&lt;/em&gt; — not the outer URL's structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Reference
&lt;/h2&gt;

&lt;p&gt;Common characters and their encoded forms:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Character&lt;/th&gt;
&lt;th&gt;Encoded&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Space&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;+&lt;/code&gt; only in form data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%26&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Query string separator — always encode in values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%3D&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Key-value separator — encode in values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;?&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%3F&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Query start — encode in values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%2F&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Path separator — encode in values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%23&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fragment — encode in values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;+&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%2B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Encode in values (means space in form encoding)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%25&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Encode existing &lt;code&gt;%&lt;/code&gt; to avoid double-encoding&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;If you're working with URLs in the browser, there's a free &lt;a href="https://snappytools.app/url-encoder-decoder/" rel="noopener noreferrer"&gt;URL Encoder / Decoder&lt;/a&gt; that handles both &lt;code&gt;encodeURIComponent&lt;/code&gt; and &lt;code&gt;encodeURI&lt;/code&gt; modes, plus batch processing for encoding lists of values at once — all client-side, so your URLs never leave the browser.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>tools</category>
    </item>
    <item>
      <title>SQL Formatting Is Not Optional: Here's Why and How</title>
      <dc:creator>Snappy Tools</dc:creator>
      <pubDate>Sat, 06 Jun 2026 10:12:32 +0000</pubDate>
      <link>https://dev.to/snappy_tools/sql-formatting-is-not-optional-heres-why-and-how-1m9j</link>
      <guid>https://dev.to/snappy_tools/sql-formatting-is-not-optional-heres-why-and-how-1m9j</guid>
      <description>&lt;p&gt;Unformatted SQL is a time sink. You spend more time parsing what a query does than understanding whether it's correct. Here's why consistent SQL formatting matters and how to do it without friction.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Unformatted SQL
&lt;/h2&gt;

&lt;p&gt;This is real SQL pulled from production code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt; &lt;span class="n"&gt;oi&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;oi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;oi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'2025-01-01'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'completed'&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Questions you can't answer at a glance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many tables are joined?&lt;/li&gt;
&lt;li&gt;What's the filtering condition?&lt;/li&gt;
&lt;li&gt;What are we ordering by?&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt; &lt;span class="n"&gt;oi&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;oi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;oi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt;
  &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'2025-01-01'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'completed'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;50&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 see the structure immediately: 4 tables, 2 filters, ordering by order total, capped at 50 rows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why SQL Formatting Gets Ignored
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ORMs hide it.&lt;/strong&gt; Developers using ActiveRecord, SQLAlchemy, or Hibernate rarely write raw SQL. When they do, it's usually urgent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;One-off queries.&lt;/strong&gt; SQL in a REPL feels temporary. No one formats throwaway code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Copy-paste from StackOverflow.&lt;/strong&gt; The query works; cleaning it up feels unnecessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No enforced linter.&lt;/strong&gt; Most CI pipelines check Python, JavaScript, and CSS formatting. SQL rarely has a linter in the chain.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Formatting Rules That Actually Matter
&lt;/h2&gt;

&lt;p&gt;These 5 rules cover 90% of cases:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. One clause per line&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Wrong&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Right&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Indent ON conditions&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;
  &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Uppercase reserved words&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Wrong&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;-- Right&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. One column per line for wide SELECTs&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Readable&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;created_at&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Align WHERE conditions&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;
  &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'active'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="k"&gt;DAY&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;role&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'admin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'editor'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  SQL in Code: Formatting Within String Literals
&lt;/h2&gt;

&lt;p&gt;When SQL lives inside application code, the formatting challenge is harder. Some approaches:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python (multi-line strings)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    SELECT
        u.id,
        u.email,
        COUNT(o.id) AS order_count
    FROM users u
    LEFT JOIN orders o ON u.id = o.user_id
    WHERE u.status = &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;
    GROUP BY u.id, u.email
    HAVING COUNT(o.id) &amp;gt; 0
    ORDER BY order_count DESC
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JavaScript (template literals)&lt;/strong&gt;&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;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
  SELECT
    user_id,
    SUM(amount) AS total
  FROM transactions
  WHERE created_at &amp;gt;= $1
  GROUP BY user_id
  ORDER BY total DESC
  LIMIT $2
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Stored procedures:&lt;/strong&gt; Keep the SQL in &lt;code&gt;.sql&lt;/code&gt; files and import them. Much easier to format, review, and diff than inline strings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Formatting Dialects
&lt;/h2&gt;

&lt;p&gt;Not all SQL is the same. MySQL, PostgreSQL, SQLite, SQL Server, and Oracle each have dialect differences:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;MySQL&lt;/th&gt;
&lt;th&gt;PostgreSQL&lt;/th&gt;
&lt;th&gt;SQL Server&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;String quoting&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;'string'&lt;/code&gt; or &lt;code&gt;"string"&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;'string'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;'string'&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Identifier quoting&lt;/td&gt;
&lt;td&gt;&lt;code&gt;`name`&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"name"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[name]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Limit syntax&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT 10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LIMIT 10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;TOP 10&lt;/code&gt; or &lt;code&gt;FETCH FIRST&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boolean&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TINYINT(1)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;BOOLEAN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;BIT&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A formatter that understands dialects will handle these correctly rather than applying a one-size-fits-all style.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Minify SQL
&lt;/h2&gt;

&lt;p&gt;Minified SQL (no whitespace) saves a tiny amount of bandwidth in query strings, but the difference is negligible for most applications. Only minify when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Embedding SQL in environment variables or config files where whitespace causes parsing issues&lt;/li&gt;
&lt;li&gt;Logging queries to a monitoring service with character limits&lt;/li&gt;
&lt;li&gt;Debugging by comparing two query strings character-by-character&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For formatting SQL in the browser — supporting MySQL, PostgreSQL, SQL Server, SQLite, and Spark dialects, with both beautify and minify modes — try the &lt;strong&gt;&lt;a href="https://snappytools.app/sql-formatter-beautifier/" rel="noopener noreferrer"&gt;SQL Formatter &amp;amp; Beautifier on SnappyTools&lt;/a&gt;&lt;/strong&gt;. Paste your query, pick your dialect, and get clean formatted output in one click. No signup required.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>tools</category>
    </item>
    <item>
      <title>Base64 Explained: Why Your API Payloads Get 33% Bigger</title>
      <dc:creator>Snappy Tools</dc:creator>
      <pubDate>Sat, 06 Jun 2026 10:08:31 +0000</pubDate>
      <link>https://dev.to/snappy_tools/base64-explained-why-your-api-payloads-get-33-bigger-25ck</link>
      <guid>https://dev.to/snappy_tools/base64-explained-why-your-api-payloads-get-33-bigger-25ck</guid>
      <description>&lt;p&gt;If you've ever embedded an image in a CSS file, read a JWT token, or sent a file via a REST API, you've used Base64. But what is it, why does it make data larger, and when should you use it?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Problem Base64 Solves
&lt;/h2&gt;

&lt;p&gt;Binary data contains every possible byte value (0–255). But many protocols — email (SMTP), HTML, XML, JSON, and older HTTP headers — were designed to carry text only. Some byte values in binary data get misinterpreted as control characters, line breaks, or encoding markers.&lt;/p&gt;

&lt;p&gt;Base64 solves this by representing any binary data using only 64 safe characters: &lt;code&gt;A–Z&lt;/code&gt;, &lt;code&gt;a–z&lt;/code&gt;, &lt;code&gt;0–9&lt;/code&gt;, &lt;code&gt;+&lt;/code&gt;, and &lt;code&gt;/&lt;/code&gt;. Every system can transmit and store these without corruption.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Base64 Works
&lt;/h2&gt;

&lt;p&gt;Base64 takes 3 bytes of input and produces 4 characters of output. This is because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3 bytes = 24 bits&lt;/li&gt;
&lt;li&gt;24 bits split into 4 groups of 6 bits each&lt;/li&gt;
&lt;li&gt;Each 6-bit group maps to one of 64 characters (2⁶ = 64)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That 3→4 ratio is where the 33% size increase comes from. Every 3 bytes becomes 4 characters, so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3 bytes input → 4 chars output
100 KB file   → ~133 KB encoded
1 MB image    → ~1.33 MB as Base64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Padding Signs (= and ==)
&lt;/h2&gt;

&lt;p&gt;If the input isn't a multiple of 3 bytes, Base64 adds padding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One &lt;code&gt;=&lt;/code&gt; means the last group had 2 bytes&lt;/li&gt;
&lt;li&gt;Two &lt;code&gt;==&lt;/code&gt; means the last group had 1 byte
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"hello" (5 bytes) → aGVsbG8=    (one padding char)
"hi"    (2 bytes) → aGk=        (two padding chars? no, one)
"a"     (1 byte)  → YQ==        (two padding chars)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most decoders handle missing padding gracefully. But if you see a &lt;code&gt;Incorrect padding&lt;/code&gt; error in Python, add &lt;code&gt;==&lt;/code&gt; to the end before decoding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Uses
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Data URIs in HTML and CSS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Embed images directly in HTML without extra HTTP requests:&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;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('data:image/svg+xml;base64,PHN2Zy...')&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;Good for small icons; avoid for large images (adds page weight and can't be cached separately).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. JWT Tokens&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;JWT tokens are three Base64URL-encoded segments separated by dots:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;eyJhbGciOiJIUzI&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;NiJ&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="err"&gt;.eyJzdWIiOiJ&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;c&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;VyMTIzIn&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;.SflKxwRJSM...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Decode the first two segments to read the header and payload — the last segment is a signature, not Base64-encoded content you should modify.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. HTTP Basic Auth&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Authorization: Basic dXNlcjpwYXNzd29yZA==
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is Base64(&lt;code&gt;username:password&lt;/code&gt;). It's not encryption — anyone can decode it. Always use HTTPS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Email Attachments (MIME)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Email protocols are text-only. MIME encodes binary attachments as Base64 and embeds them in the email body. This is why a 1 MB PDF attachment adds ~1.33 MB to the email size.&lt;/p&gt;

&lt;h2&gt;
  
  
  Base64 vs URL-Safe Base64
&lt;/h2&gt;

&lt;p&gt;Standard Base64 uses &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;/&lt;/code&gt;, which are reserved characters in URLs. URL-safe Base64 replaces them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;+&lt;/code&gt; → &lt;code&gt;-&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/&lt;/code&gt; → &lt;code&gt;_&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Padding &lt;code&gt;=&lt;/code&gt; is often omitted entirely&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use URL-safe Base64 when embedding encoded data in URL parameters. JWT tokens use URL-safe Base64.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Reference by Language
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;JavaScript (browser)&lt;/strong&gt;&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="c1"&gt;// Encode&lt;/span&gt;
&lt;span class="nf"&gt;btoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="c1"&gt;// "aGVsbG8gd29ybGQ="&lt;/span&gt;

&lt;span class="c1"&gt;// Decode&lt;/span&gt;
&lt;span class="nf"&gt;atob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aGVsbG8gd29ybGQ=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;// "hello world"&lt;/span&gt;

&lt;span class="c1"&gt;// URL-safe (no built-in, add manually)&lt;/span&gt;
&lt;span class="nf"&gt;btoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\+&lt;/span&gt;&lt;span class="sr"&gt;/g&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="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sr"&gt;/g&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="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/=/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;

&lt;span class="c1"&gt;# Standard
&lt;/span&gt;&lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello world&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;       &lt;span class="c1"&gt;# "aGVsbG8gd29ybGQ="
&lt;/span&gt;&lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;b64decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aGVsbG8gd29ybGQ=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;           &lt;span class="c1"&gt;# b"hello world"
&lt;/span&gt;
&lt;span class="c1"&gt;# URL-safe
&lt;/span&gt;&lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlsafe_b64encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello world&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlsafe_b64decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aGVsbG8gd29ybGQ=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Java&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Base64&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.nio.charset.StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Encode&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Base64&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEncoder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;encodeToString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;UTF_8&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Decode&lt;/span&gt;
&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;decoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Base64&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDecoder&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;decode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encoded&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decoded&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;UTF_8&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// URL-safe&lt;/span&gt;
&lt;span class="nc"&gt;Base64&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUrlEncoder&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;encodeToString&lt;/span&gt;&lt;span class="o"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Command line&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Encode&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt;           &lt;span class="c"&gt;# aGVsbG8=&lt;/span&gt;

&lt;span class="c"&gt;# Decode&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"aGVsbG8="&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;       &lt;span class="c"&gt;# hello&lt;/span&gt;

&lt;span class="c"&gt;# Encode a file&lt;/span&gt;
&lt;span class="nb"&gt;base64 &lt;/span&gt;image.png &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; image.txt

&lt;span class="c"&gt;# Decode a file&lt;/span&gt;
&lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; image.txt &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; image_decoded.png
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Base64 Is NOT
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Not compression&lt;/strong&gt; — it makes data ~33% larger&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not encryption&lt;/strong&gt; — anyone can decode it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not hashing&lt;/strong&gt; — it's reversible; SHA/MD5 are not&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When NOT to Use Base64
&lt;/h2&gt;

&lt;p&gt;Don't encode large binary files and embed them in JSON if you can serve them as file downloads. The size increase and the inability to cache encoded content separately makes Base64 a poor choice for images over 10–20 KB in production.&lt;/p&gt;

&lt;p&gt;For quick encode/decode in the browser — including URL-safe mode and batch mode — try the &lt;strong&gt;&lt;a href="https://snappytools.app/base64-encoder-decoder/" rel="noopener noreferrer"&gt;Base64 Encoder &amp;amp; Decoder on SnappyTools&lt;/a&gt;&lt;/strong&gt;. No signup, runs entirely in your browser, no data sent anywhere.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>tools</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Lorem Ipsum for Developers: Stop Hardcoding Placeholder Text</title>
      <dc:creator>Snappy Tools</dc:creator>
      <pubDate>Sat, 06 Jun 2026 10:08:30 +0000</pubDate>
      <link>https://dev.to/snappy_tools/lorem-ipsum-for-developers-stop-hardcoding-placeholder-text-3j6a</link>
      <guid>https://dev.to/snappy_tools/lorem-ipsum-for-developers-stop-hardcoding-placeholder-text-3j6a</guid>
      <description>&lt;p&gt;Every developer has done it: opened a new project, needed some placeholder text, and typed "test test test" or copy-pasted the same three sentences from an old project. There's a better way.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Lorem Ipsum Actually Is
&lt;/h2&gt;

&lt;p&gt;Lorem ipsum is not random gibberish. It's derived from Cicero's philosophical work &lt;em&gt;De Finibus Bonorum et Malorum&lt;/em&gt; (45 BC), deliberately scrambled so the words carry no meaning. This is the point — when reviewers read meaningful text, they critique the words. When they see lorem ipsum, they focus on the design.&lt;/p&gt;

&lt;p&gt;The classic opening — "Lorem ipsum dolor sit amet..." — has been the default placeholder in print and digital design since Letraset used it in the 1960s, and then Aldus PageMaker made it the default in the 1980s.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Static Lorem Ipsum
&lt;/h2&gt;

&lt;p&gt;Most developers copy the same lorem ipsum paragraph everywhere. This creates a few problems:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layouts optimised for one text length.&lt;/strong&gt; If your card always shows 75 words of placeholder, you'll never notice it breaks with 20 words or 200 words.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repetition looks wrong.&lt;/strong&gt; Stakeholder reviews with 8 identical paragraphs don't represent how the final page will look.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wrong format for the use case.&lt;/strong&gt; Sometimes you need HTML &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tags. Sometimes you need a JSON array for a mock API. Copying plain text and manually wrapping it wastes time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate Lorem Ipsum in Different Formats
&lt;/h2&gt;

&lt;p&gt;Here's what you actually need from a lorem ipsum generator:&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="c"&gt;&amp;lt;!-- HTML format — paste directly into templates --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Sed do eiusmod tempor incididunt ut labore et dolore...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JSON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;—&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;paste&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;into&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;mock&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;API&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;responses&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fixtures&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"Lorem ipsum dolor sit amet, consectetur adipiscing elit..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"Sed do eiusmod tempor incididunt ut labore et dolore..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Markdown format — paste into .md files or documentation --&amp;gt;&lt;/span&gt;
Lorem ipsum dolor sit amet, consectetur adipiscing elit...

Sed do eiusmod tempor incididunt ut labore et dolore...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Quick Shortcuts in Code Editors
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;VS Code:&lt;/strong&gt; Type &lt;code&gt;lorem&lt;/code&gt; in any HTML file and press &lt;code&gt;Tab&lt;/code&gt;. Emmet generates a paragraph automatically. Use &lt;code&gt;lorem*3&lt;/code&gt; to generate 3 paragraphs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JetBrains IDEs (WebStorm, PhpStorm):&lt;/strong&gt; Type &lt;code&gt;lorem&lt;/code&gt; and press &lt;code&gt;Tab&lt;/code&gt; for one sentence. Some versions support &lt;code&gt;lorem100&lt;/code&gt; to generate 100 words.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WordPress Gutenberg:&lt;/strong&gt; Type &lt;code&gt;/lorem&lt;/code&gt; in a new paragraph block and press Enter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google Docs:&lt;/strong&gt; Type &lt;code&gt;=lorem()&lt;/code&gt; and press Enter for one paragraph. &lt;code&gt;=lorem(3)&lt;/code&gt; gives three paragraphs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Microsoft Word:&lt;/strong&gt; Type &lt;code&gt;=lorem(3,5)&lt;/code&gt; — 3 paragraphs of 5 sentences each.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate Lorem Ipsum in JavaScript
&lt;/h2&gt;

&lt;p&gt;For dynamic placeholder text in React, Vue, or plain JS:&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="c1"&gt;// Using the lorem-ipsum npm package&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LoremIpsum&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;lorem-ipsum&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;lorem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LoremIpsum&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;sentencesPerParagraph&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;wordsPerSentence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Generate 3 paragraphs&lt;/span&gt;
&lt;span class="nx"&gt;lorem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateParagraphs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Generate 5 sentences&lt;/span&gt;
&lt;span class="nx"&gt;lorem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSentences&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Generate 50 words&lt;/span&gt;
&lt;span class="nx"&gt;lorem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateWords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or with Faker.js (if you're already using it for test data):&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;faker&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;@faker-js/faker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;faker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lorem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paragraphs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// 3 paragraphs&lt;/span&gt;
&lt;span class="nx"&gt;faker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lorem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sentences&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;// 5 sentences&lt;/span&gt;
&lt;span class="nx"&gt;faker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lorem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;words&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// 50 words&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Generate Lorem Ipsum in Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;lorem&lt;/span&gt;

&lt;span class="c1"&gt;# One paragraph
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lorem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paragraph&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="c1"&gt;# One sentence
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lorem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="c1"&gt;# Three words
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lorem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_word&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or with the Faker library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;faker&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Faker&lt;/span&gt;
&lt;span class="n"&gt;fake&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Faker&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# 3 paragraphs
&lt;/span&gt;&lt;span class="n"&gt;fake&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paragraphs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 5 sentences
&lt;/span&gt;&lt;span class="n"&gt;fake&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sentences&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The 100-Word Rule for Testing
&lt;/h2&gt;

&lt;p&gt;When testing a layout, generate three variants:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Short:&lt;/strong&gt; 10–20 words (button labels, card titles)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medium:&lt;/strong&gt; 50–100 words (card descriptions, sidebars)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Long:&lt;/strong&gt; 200–400 words (article bodies, feature descriptions)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A layout that handles all three is a layout that handles real content. A layout tested with only one length will break in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  When NOT to Use Lorem Ipsum
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hero sections and headings&lt;/strong&gt; — real copy reveals whether headlines fit the layout&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CTAs and buttons&lt;/strong&gt; — word count matters for button sizing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High-fidelity prototypes&lt;/strong&gt; — stakeholders need real content to give useful feedback&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO pages&lt;/strong&gt; — lorem ipsum in production signals low-quality content to Google&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For quick generation in any format — plain text, HTML, Markdown, or JSON — try the &lt;strong&gt;&lt;a href="https://snappytools.app/lorem-ipsum-generator/" rel="noopener noreferrer"&gt;Lorem Ipsum Generator on SnappyTools&lt;/a&gt;&lt;/strong&gt;. It randomises on every copy so repeated pastes produce varied text, and it shows the exact word and character count so you know what you're pasting.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>beginners</category>
      <category>tools</category>
    </item>
    <item>
      <title>CSS Gradient Animations: Three Techniques That Actually Work</title>
      <dc:creator>Snappy Tools</dc:creator>
      <pubDate>Fri, 05 Jun 2026 10:11:27 +0000</pubDate>
      <link>https://dev.to/snappy_tools/css-gradient-animations-three-techniques-that-actually-work-1n6i</link>
      <guid>https://dev.to/snappy_tools/css-gradient-animations-three-techniques-that-actually-work-1n6i</guid>
      <description>&lt;p&gt;Animated gradients are one of those effects that look impressive but have a surprising number of wrong ways to implement them. CSS can't natively interpolate gradient stop colours, which means you can't just write &lt;code&gt;transition: background 0.5s&lt;/code&gt; and expect it to work. This post covers three techniques that do work, with the trade-offs for each.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why transition: background Doesn't Work on Gradients
&lt;/h2&gt;

&lt;p&gt;Browsers can animate &lt;code&gt;background-color&lt;/code&gt; smoothly. But &lt;code&gt;background: linear-gradient(...)&lt;/code&gt; is not a colour — it's an image value. CSS treats it the same way as &lt;code&gt;background: url(photo.jpg)&lt;/code&gt;. You can't smoothly transition between two image values, so the browser just jumps from one to the other with no animation.&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="c"&gt;/* This doesn't animate — it just snaps */&lt;/span&gt;
&lt;span class="nc"&gt;.box&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;135deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#6c63ff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#f43f8a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="m"&gt;0.5s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* has no effect on the gradient */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.box&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;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;135deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#f43f8a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#68d391&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;Here are three approaches that actually work.&lt;/p&gt;




&lt;h2&gt;
  
  
  Technique 1: Background-Position Shift (Pure CSS, Most Compatible)
&lt;/h2&gt;

&lt;p&gt;The trick: make the gradient much larger than its container, then animate &lt;code&gt;background-position&lt;/code&gt;. The gradient itself doesn't change — it just slides.&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;.animated-gradient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="m"&gt;270deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;#6c63ff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#f43f8a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#68d391&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#6c63ff&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;background-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;400%&lt;/span&gt; &lt;span class="m"&gt;400%&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;gradientShift&lt;/span&gt; &lt;span class="m"&gt;6s&lt;/span&gt; &lt;span class="n"&gt;ease&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;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;gradientShift&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;background-position&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;50%&lt;/span&gt;&lt;span class="p"&gt;;&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;background-position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&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="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;background-position&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;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;&lt;strong&gt;How it works:&lt;/strong&gt; The gradient is 4× the width of the element. The keyframes shift the visible window from left to right and back. Since the start and end colours match, it loops seamlessly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro:&lt;/strong&gt; Pure CSS, works everywhere, very smooth.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Con:&lt;/strong&gt; The animation is a sliding motion, not a colour interpolation — different from a true colour-changing gradient. Also need to duplicate the start colour at the end for seamless looping.&lt;/p&gt;


&lt;h2&gt;
  
  
  Technique 2: Opacity Crossfade (True Colour Change, No JavaScript)
&lt;/h2&gt;

&lt;p&gt;Layer two gradients using pseudo-elements and crossfade their opacity:&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;.crossfade-gradient&lt;/span&gt; &lt;span class="p"&gt;{&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;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.crossfade-gradient&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.crossfade-gradient&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&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="py"&gt;inset&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="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inherit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.crossfade-gradient&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;135deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#6c63ff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#f43f8a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.crossfade-gradient&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;135deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#f43f8a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#68d391&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;crossfade&lt;/span&gt; &lt;span class="m"&gt;3s&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="n"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;crossfade&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;opacity&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;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&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;&lt;strong&gt;How it works:&lt;/strong&gt; One gradient sits on &lt;code&gt;::before&lt;/code&gt;, another on &lt;code&gt;::after&lt;/code&gt;. Fading the &lt;code&gt;::after&lt;/code&gt; opacity from 0 to 1 creates the impression that the gradient is changing colour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro:&lt;/strong&gt; Looks like a true gradient colour change. No JavaScript.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Con:&lt;/strong&gt; Uses both pseudo-elements (can't use them for other purposes). Requires &lt;code&gt;position: relative&lt;/code&gt; on the parent. You only get two states.&lt;/p&gt;


&lt;h2&gt;
  
  
  Technique 3: CSS Custom Properties + JavaScript (Most Flexible)
&lt;/h2&gt;

&lt;p&gt;Define the gradient using CSS variables and update them in JavaScript:&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;.js-gradient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--angle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;135deg&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color-start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#6c63ff&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color-end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#f43f8a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--angle&lt;/span&gt; &lt;span class="m"&gt;0.5s&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;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;el&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.js-gradient&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;hue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;hue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hue&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--color-start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`hsl(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, 70%, 60%)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--color-end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`hsl(&lt;/span&gt;&lt;span class="p"&gt;${(&lt;/span&gt;&lt;span class="nx"&gt;hue&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, 70%, 60%)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; CSS custom properties can be transitioned if registered with &lt;code&gt;@property&lt;/code&gt; (Houdini). Even without registration, JavaScript updates them in a &lt;code&gt;requestAnimationFrame&lt;/code&gt; loop creating smooth frame-by-frame changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro:&lt;/strong&gt; Complete control. You can animate angle, colour, number of stops, or anything. Works with any gradient shape.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Con:&lt;/strong&gt; Requires JavaScript. For the &lt;code&gt;transition&lt;/code&gt; on custom properties to work, you need &lt;code&gt;@property&lt;/code&gt; (supported in Chrome and Edge, not Firefox as of 2024).&lt;/p&gt;


&lt;h2&gt;
  
  
  Animating the Gradient Angle
&lt;/h2&gt;

&lt;p&gt;All three techniques can animate the gradient direction. The simplest approach with pure CSS:&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;.rotating-gradient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;conic-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--angle&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="m"&gt;#6c63ff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#f43f8a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#68d391&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#6c63ff&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;rotate&lt;/span&gt; &lt;span class="m"&gt;4s&lt;/span&gt; &lt;span class="n"&gt;linear&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;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--angle&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="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;For this to work smoothly, register the property:&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;@property&lt;/span&gt; &lt;span class="n"&gt;--angle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;syntax&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"&amp;lt;angle&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;initial-value&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="py"&gt;inherits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&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;Without &lt;code&gt;@property&lt;/code&gt;, the conic rotation will jump rather than animate smoothly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance Note
&lt;/h2&gt;

&lt;p&gt;Gradient animations trigger a repaint on every frame. To keep performance high:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;code&gt;will-change: background&lt;/code&gt; (or &lt;code&gt;will-change: transform&lt;/code&gt; if you're moving the element)&lt;/li&gt;
&lt;li&gt;Keep the animated element on its own compositing layer&lt;/li&gt;
&lt;li&gt;Prefer opacity/transform changes over background changes where possible — those run on the GPU compositor thread&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For UI backgrounds and hero sections, all three techniques are fast enough on modern hardware. For 60+ simultaneous animated gradient elements, consider WebGL.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Technique&lt;/th&gt;
&lt;th&gt;JavaScript?&lt;/th&gt;
&lt;th&gt;Looks like&lt;/th&gt;
&lt;th&gt;Compatibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;background-size shift&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Sliding gradient&lt;/td&gt;
&lt;td&gt;All browsers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Opacity crossfade&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Colour change&lt;/td&gt;
&lt;td&gt;All browsers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSS variables + JS&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Anything&lt;/td&gt;
&lt;td&gt;Modern browsers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@property + conic&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Rotating gradient&lt;/td&gt;
&lt;td&gt;Chrome/Edge only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For a visual gradient editor that generates the base CSS for any of these techniques, use the free &lt;a href="https://snappytools.app/gradient-generator/" rel="noopener noreferrer"&gt;CSS Gradient Generator&lt;/a&gt; at SnappyTools — copy the CSS and wrap it in the animation keyframes shown above.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Open Graph Tags Explained: How to Control What Shows When You Share a Link</title>
      <dc:creator>Snappy Tools</dc:creator>
      <pubDate>Fri, 05 Jun 2026 10:11:26 +0000</pubDate>
      <link>https://dev.to/snappy_tools/open-graph-tags-explained-how-to-control-what-shows-when-you-share-a-link-438j</link>
      <guid>https://dev.to/snappy_tools/open-graph-tags-explained-how-to-control-what-shows-when-you-share-a-link-438j</guid>
      <description>&lt;p&gt;Every time you paste a URL into Slack, Twitter, LinkedIn, or iMessage, those apps fetch metadata from the page and display a rich preview card: title, image, description. That preview is controlled entirely by &lt;strong&gt;Open Graph meta tags&lt;/strong&gt; — a set of HTML &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tags that almost every developer adds incorrectly or forgets entirely.&lt;/p&gt;

&lt;p&gt;This guide covers what they are, which ones actually matter, and how to add them properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Open Graph Tags?
&lt;/h2&gt;

&lt;p&gt;Open Graph was created by Facebook in 2010 and is now a web standard. They live in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; of your HTML document:&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;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:title"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Your Page Title"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"A short description of the page."&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:image"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/images/og-image.jpg"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:url"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/your-page/"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:type"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"website"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:site_name"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Your Site Name"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a social platform or messaging app fetches your URL, it reads these tags to build the preview card. Without them, it guesses — usually badly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tags That Actually Matter
&lt;/h2&gt;

&lt;h3&gt;
  
  
  og:title
&lt;/h3&gt;

&lt;p&gt;The title displayed in the link preview. It doesn't have to match the page's &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; tag — often a slightly shorter, punchier version works better for social sharing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended length:&lt;/strong&gt; 60–70 characters.&lt;/p&gt;

&lt;h3&gt;
  
  
  og:description
&lt;/h3&gt;

&lt;p&gt;The description shown below the title in the preview card. This is your one sentence to make someone decide whether to click.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended length:&lt;/strong&gt; 120–155 characters. Don't repeat the title.&lt;/p&gt;

&lt;h3&gt;
  
  
  og:image
&lt;/h3&gt;

&lt;p&gt;The image shown in the preview card. This has the biggest impact on click-through rate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minimum size: 1200×630 pixels (Facebook recommends this for best display across all placements)&lt;/li&gt;
&lt;li&gt;Format: JPG or PNG (WebP has inconsistent support)&lt;/li&gt;
&lt;li&gt;File size: under 1 MB&lt;/li&gt;
&lt;li&gt;Must be an absolute URL (not a relative path)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you leave this out, platforms will either show nothing or try to grab any image from the page — usually your logo thumbnail or an ad.&lt;/p&gt;

&lt;h3&gt;
  
  
  og:url
&lt;/h3&gt;

&lt;p&gt;The canonical URL of the page. This prevents duplicate sharing counts when the same content is accessible at multiple URLs (with/without trailing slash, http vs https, etc.).&lt;/p&gt;

&lt;h3&gt;
  
  
  og:type
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;website&lt;/code&gt; for most pages. Use &lt;code&gt;article&lt;/code&gt; for blog posts, and then add article-specific tags:&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;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:type"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"article"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"article:author"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"https://yoursite.com/about/"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"article:published_time"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"2024-05-31T10:00:00Z"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Twitter Card Tags
&lt;/h2&gt;

&lt;p&gt;Twitter/X uses its own tag format. You need these in addition to OG tags:&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;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:card"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"summary_large_image"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:title"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Your Page Title"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Your description."&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:image"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/images/og-image.jpg"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;summary_large_image&lt;/code&gt; gives you the full-width image preview. &lt;code&gt;summary&lt;/code&gt; gives the small thumbnail on the left. For any content with a compelling image, use &lt;code&gt;summary_large_image&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Twitter also accepts the og: versions if twitter: tags are missing, but explicit twitter: tags give you more control.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Complete Template
&lt;/h2&gt;

&lt;p&gt;Here's the full set to add to every page:&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="c"&gt;&amp;lt;!-- Open Graph --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:title"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Page Title — Site Name"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"One sentence describing what's on this page."&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:image"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/og-image.jpg"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:url"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/this-page/"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:type"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"website"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:site_name"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Site Name"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Twitter Card --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:card"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"summary_large_image"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:title"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Page Title — Site Name"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"One sentence describing what's on this page."&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:image"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/og-image.jpg"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Standard meta (still matters for search engines) --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"One sentence describing what's on this page."&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Common Mistakes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Forgetting og:image&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The single most impactful tag. A link preview without an image gets dramatically fewer clicks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Using a relative path for og:image&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;code&gt;/images/og.jpg&lt;/code&gt; won't work — it must be a full URL including protocol and domain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Using the same image for every page&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This works for the homepage, but article pages should have unique images that hint at the content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. og:title over 70 characters&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Platforms truncate longer titles, often mid-word.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Not validating after deploy&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Social platforms cache metadata aggressively. After adding or changing OG tags, validate using Twitter's Card Validator or Facebook's Sharing Debugger to force a cache refresh.&lt;/p&gt;

&lt;h2&gt;
  
  
  Platform-Specific Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: uses og:title, og:description, og:image, og:url — reads og: tags, not twitter: tags&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slack&lt;/strong&gt;: uses og: tags; will fallback to &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; if og:title is missing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;iMessage / WhatsApp&lt;/strong&gt;: use og: tags for link previews&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discord&lt;/strong&gt;: uses og: tags; supports og:video for embedded players&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tag&lt;/th&gt;
&lt;th&gt;Required?&lt;/th&gt;
&lt;th&gt;Max Length&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;og:title&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;70 chars&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;og:description&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;155 chars&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;og:image&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;— (1200×630px recommended)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;og:url&lt;/td&gt;
&lt;td&gt;Recommended&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;og:type&lt;/td&gt;
&lt;td&gt;Recommended&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;og:site_name&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;twitter:card&lt;/td&gt;
&lt;td&gt;Yes for Twitter&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For a quick way to generate and preview your OG tags as they'd appear on Twitter, Facebook, and LinkedIn, try the developer tools at &lt;a href="https://snappytools.app/" rel="noopener noreferrer"&gt;SnappyTools&lt;/a&gt; — specifically the &lt;a href="https://snappytools.app/html-entity-encoder/" rel="noopener noreferrer"&gt;HTML Entity Encoder&lt;/a&gt; for any special characters in your titles and descriptions.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>beginners</category>
      <category>html</category>
    </item>
    <item>
      <title>Unix Timestamps Explained: The Developer's Complete Reference</title>
      <dc:creator>Snappy Tools</dc:creator>
      <pubDate>Fri, 05 Jun 2026 10:09:15 +0000</pubDate>
      <link>https://dev.to/snappy_tools/unix-timestamps-explained-the-developers-complete-reference-173o</link>
      <guid>https://dev.to/snappy_tools/unix-timestamps-explained-the-developers-complete-reference-173o</guid>
      <description>&lt;p&gt;Unix timestamps are one of those concepts that every developer encounters constantly but rarely stops to fully understand. They appear in log files, database columns, API responses, and cookie headers. This guide covers everything you need to know — from what they are to language-specific conversion code for every major language.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Unix Timestamp?
&lt;/h2&gt;

&lt;p&gt;A Unix timestamp is a single integer representing the number of &lt;strong&gt;seconds elapsed since January 1, 1970, 00:00:00 UTC&lt;/strong&gt; — known as the Unix epoch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1717200000  ← this is a Unix timestamp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The epoch date (January 1, 1970) was chosen by Bell Labs engineers when designing Unix. It was simply a convenient, recent reference point that allowed 32-bit integers to cover a useful date range (1901–2038). Modern systems use 64-bit integers, extending the range to hundreds of billions of years.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seconds vs Milliseconds: The Gotcha
&lt;/h2&gt;

&lt;p&gt;This is the source of more bugs than almost any other timestamp issue:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;System&lt;/th&gt;
&lt;th&gt;Unit&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Unix/POSIX&lt;/td&gt;
&lt;td&gt;Seconds&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;1717200000&lt;/code&gt; (10 digits)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JavaScript (Date.now())&lt;/td&gt;
&lt;td&gt;Milliseconds&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;1717200000000&lt;/code&gt; (13 digits)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Java (System.currentTimeMillis())&lt;/td&gt;
&lt;td&gt;Milliseconds&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1717200000000&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Rule of thumb:&lt;/strong&gt; if the number has 13 digits, it's milliseconds. If it has 10 digits, it's seconds. Always check which unit your API or database is using before converting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Converting a Timestamp to a Date in Every Major Language
&lt;/h2&gt;

&lt;h3&gt;
  
  
  JavaScript
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Timestamp → date (JavaScript uses milliseconds)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1717200000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// "2024-05-31T16:00:00.000Z"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// local time&lt;/span&gt;

&lt;span class="c1"&gt;// Current timestamp in seconds&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="c1"&gt;# Timestamp → datetime
&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromtimestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1717200000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tz&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 2024-05-31 16:00:00+00:00
&lt;/span&gt;
&lt;span class="c1"&gt;# Current timestamp
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  PHP
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Timestamp → formatted date&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Y-m-d H:i:s'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1717200000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// "2024-05-31 16:00:00" (local)&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nb"&gt;gmdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Y-m-d H:i:s'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1717200000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "2024-05-31 16:00:00" (UTC)&lt;/span&gt;

&lt;span class="c1"&gt;// Current timestamp&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Go
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"time"&lt;/span&gt;

&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1717200000&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTC&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RFC3339&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c"&gt;// "2024-05-31T16:00:00Z"&lt;/span&gt;

&lt;span class="c"&gt;// Current timestamp&lt;/span&gt;
&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unix&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ruby
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1717200000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;utc&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; 2024-05-31 16:00:00 UTC&lt;/span&gt;
&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt;             &lt;span class="c1"&gt;# current timestamp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  C# (.NET)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Timestamp → DateTime&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTimeOffset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromUnixTimeSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1717200000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;UtcDateTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Current timestamp&lt;/span&gt;
&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTimeOffset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToUnixTimeSeconds&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Java
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Instant&lt;/span&gt; &lt;span class="n"&gt;instant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Instant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofEpochSecond&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1717200000L&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;LocalDateTime&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LocalDateTime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofInstant&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instant&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ZoneOffset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;UTC&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Current timestamp&lt;/span&gt;
&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Instant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;now&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getEpochSecond&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  SQL
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- MySQL: timestamp → datetime&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;FROM_UNIXTIME&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1717200000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;-- '2024-05-31 16:00:00'&lt;/span&gt;

&lt;span class="c1"&gt;-- PostgreSQL: timestamp → timestamptz&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;to_timestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1717200000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;-- 2024-05-31 16:00:00+00&lt;/span&gt;

&lt;span class="c1"&gt;-- Current timestamp&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;UNIX_TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;-- MySQL&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;EXTRACT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EPOCH&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;  &lt;span class="c1"&gt;-- PostgreSQL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Timezone Pitfalls
&lt;/h2&gt;

&lt;p&gt;Unix timestamps are always in UTC — they have no timezone. The confusion happens when you convert them to human-readable dates. Different languages apply the local timezone by default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Python: fromtimestamp() uses local time!
&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromtimestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;# Local time — dangerous
&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcfromtimestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Naive UTC — better
&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromtimestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tz&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Timezone-aware UTC — best
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Best practice:&lt;/strong&gt; always work in UTC and only convert to local time at the display layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Year 2038 Problem
&lt;/h2&gt;

&lt;p&gt;Systems that store Unix timestamps in 32-bit signed integers will overflow at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2,147,483,647 seconds → 19 January 2038, 03:14:07 UTC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, the value wraps to a large negative number, jumping back to 1901. This affects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Old databases with &lt;code&gt;INT&lt;/code&gt; timestamp columns&lt;/li&gt;
&lt;li&gt;32-bit embedded systems&lt;/li&gt;
&lt;li&gt;Legacy C code using &lt;code&gt;time_t&lt;/code&gt; on 32-bit platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Modern 64-bit systems are safe&lt;/strong&gt; until approximately the year 292 billion. If you're writing new code, always store timestamps as &lt;code&gt;BIGINT&lt;/code&gt; in databases and 64-bit integer types in code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Does Timestamp 0 Mean?
&lt;/h2&gt;

&lt;p&gt;Unix timestamp &lt;code&gt;0&lt;/code&gt; is the epoch itself: &lt;strong&gt;1970-01-01 00:00:00 UTC&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's commonly used as a sentinel value meaning "not set" or "no date" in older code. Be careful: some validation code mistakenly treats &lt;code&gt;0&lt;/code&gt; as invalid when it actually represents a perfectly valid date (January 1, 1970).&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Conversion Tool
&lt;/h2&gt;

&lt;p&gt;If you need to convert timestamps without writing code, use the &lt;strong&gt;&lt;a href="https://snappytools.app/unix-timestamp-converter/" rel="noopener noreferrer"&gt;Unix Timestamp Converter&lt;/a&gt;&lt;/strong&gt; — it converts in both directions (timestamp ↔ date), shows the current live timestamp, supports all timezones, and displays relative time. No signup, runs in your browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A Unix timestamp is seconds since 1970-01-01 00:00:00 UTC&lt;/li&gt;
&lt;li&gt;JavaScript and Java use milliseconds — always check which unit you're receiving&lt;/li&gt;
&lt;li&gt;Convert to local time only at the display layer; store and transmit in UTC&lt;/li&gt;
&lt;li&gt;Use 64-bit integers to avoid the Year 2038 problem&lt;/li&gt;
&lt;li&gt;Timestamp 0 = the Unix epoch (January 1, 1970), not "invalid"&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>javascript</category>
    </item>
    <item>
      <title>SQL Formatting: Why It Matters More Than You Think (and How to Do It Right)</title>
      <dc:creator>Snappy Tools</dc:creator>
      <pubDate>Thu, 04 Jun 2026 10:05:45 +0000</pubDate>
      <link>https://dev.to/snappy_tools/sql-formatting-why-it-matters-more-than-you-think-and-how-to-do-it-right-1koa</link>
      <guid>https://dev.to/snappy_tools/sql-formatting-why-it-matters-more-than-you-think-and-how-to-do-it-right-1koa</guid>
      <description>&lt;p&gt;Nobody disputes that code should be readable. But somehow, SQL gets a pass — compressed into a single line, aliases that are single letters, subqueries nested four levels deep. Here's why that's a mistake and what good SQL formatting actually looks like.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why SQL Formatting Gets Ignored
&lt;/h2&gt;

&lt;p&gt;A few reasons SQL readability gets neglected:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;It "works" either way.&lt;/strong&gt; The database doesn't care about whitespace.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ORMs hide the SQL.&lt;/strong&gt; Developers who write Hibernate or SQLAlchemy rarely see raw SQL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No enforced style guide.&lt;/strong&gt; Python has PEP 8; SQL has no universally adopted equivalent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy-paste culture.&lt;/strong&gt; SQL often comes from Stack Overflow or query builders, pre-minified.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The cost shows up in code review ("wait, what does this actually do?"), debugging ("where does this subquery start?"), and onboarding ("who wrote this and can I call them?").&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Rules
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Keywords in uppercase (or consistently lower)
&lt;/h3&gt;

&lt;p&gt;Pick one and stick to it. Most style guides prefer uppercase keywords because it creates visual hierarchy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Good&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'2026-01-01'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;is_active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Acceptable (consistent lowercase)&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'2026-01-01'&lt;/span&gt;
  &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;is_active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;order&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;asc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  One clause per line
&lt;/h3&gt;

&lt;p&gt;Each major clause (&lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;FROM&lt;/code&gt;, &lt;code&gt;WHERE&lt;/code&gt;, &lt;code&gt;JOIN&lt;/code&gt;, &lt;code&gt;GROUP BY&lt;/code&gt;, &lt;code&gt;ORDER BY&lt;/code&gt;) starts on its own line. Conditions within a clause are indented:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;order_count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'2026-01-01'&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;order_count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Alias everything, but name it well
&lt;/h3&gt;

&lt;p&gt;Single-letter aliases (&lt;code&gt;u&lt;/code&gt;, &lt;code&gt;o&lt;/code&gt;) are fine in short queries. In long queries, use descriptive aliases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Short: fine&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Long: be descriptive&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;active_users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;recent_orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;active_users&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;recent_orders&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;recent_orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;active_users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Subqueries: always indent
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; 
        &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_spent&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'completed'&lt;/span&gt;
    &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;spending&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;spending&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total_spent&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CTEs over nested subqueries
&lt;/h3&gt;

&lt;p&gt;Common Table Expressions make complex logic readable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;active_users&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;is_active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;high_spenders&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
    &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;
    &lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;au&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;hs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;active_users&lt;/span&gt; &lt;span class="n"&gt;au&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;high_spenders&lt;/span&gt; &lt;span class="n"&gt;hs&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;hs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;au&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;hs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Formatting Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Element&lt;/th&gt;
&lt;th&gt;Convention&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Keywords&lt;/td&gt;
&lt;td&gt;UPPERCASE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Table/column names&lt;/td&gt;
&lt;td&gt;lowercase_snake_case&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aliases&lt;/td&gt;
&lt;td&gt;AS keyword (explicit)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commas&lt;/td&gt;
&lt;td&gt;End of line (trailing) or start of line (leading) — pick one&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Indentation&lt;/td&gt;
&lt;td&gt;4 spaces (not tabs)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Line length&lt;/td&gt;
&lt;td&gt;Max 100 chars&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Semicolons&lt;/td&gt;
&lt;td&gt;Always close statements&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Tools That Help
&lt;/h2&gt;

&lt;p&gt;Running raw SQL through a formatter before committing it takes about 5 seconds and saves everyone who reads it later 5 minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://snappytools.app/sql-formatter-beautifier/" rel="noopener noreferrer"&gt;SnappyTools SQL Formatter &amp;amp; Beautifier&lt;/a&gt;&lt;/strong&gt; formats any SQL query in the browser — supports indentation, keyword casing, and basic dialect-aware formatting. Paste in the ugly version, copy out the clean version.&lt;/p&gt;

&lt;p&gt;No account, no upload, runs locally in your browser.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Do you have a team SQL style guide? Or does every developer format differently?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>sql</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>CSS Gradients in 2026: Linear, Radial, and Conic — A Complete Reference</title>
      <dc:creator>Snappy Tools</dc:creator>
      <pubDate>Thu, 04 Jun 2026 10:03:53 +0000</pubDate>
      <link>https://dev.to/snappy_tools/css-gradients-in-2026-linear-radial-and-conic-a-complete-reference-4bbo</link>
      <guid>https://dev.to/snappy_tools/css-gradients-in-2026-linear-radial-and-conic-a-complete-reference-4bbo</guid>
      <description>&lt;p&gt;CSS gradients are one of those features that look simple until you try to do something precise with them. Here's everything you need to know — syntax, angles, colour stops, and the patterns that show up in real projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Types
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Linear Gradient
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;color-stop1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;color-stop2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Direction can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An angle: &lt;code&gt;45deg&lt;/code&gt;, &lt;code&gt;135deg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A keyword: &lt;code&gt;to right&lt;/code&gt;, &lt;code&gt;to bottom right&lt;/code&gt;, &lt;code&gt;to top&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="c"&gt;/* Left to right */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="nt"&gt;right&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;#2&lt;/span&gt;&lt;span class="nt"&gt;f855a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;#68&lt;/span&gt;&lt;span class="nt"&gt;d391&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c"&gt;/* 45° diagonal */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;45&lt;/span&gt;&lt;span class="nt"&gt;deg&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;#667&lt;/span&gt;&lt;span class="nt"&gt;eea&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;#764&lt;/span&gt;&lt;span class="nt"&gt;ba2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c"&gt;/* Three stops */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="nt"&gt;right&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;#f6d365&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;#fda085&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;#f093fb&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Angle reference:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;0deg&lt;/code&gt; = bottom to top&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;90deg&lt;/code&gt; = left to right
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;180deg&lt;/code&gt; = top to bottom (same as &lt;code&gt;to bottom&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;270deg&lt;/code&gt; = right to left&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Radial Gradient
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;shape&lt;/span&gt; &lt;span class="nt"&gt;size&lt;/span&gt; &lt;span class="nt"&gt;at&lt;/span&gt; &lt;span class="nt"&gt;position&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;start-color&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;end-color&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Default: ellipse from center */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;#667&lt;/span&gt;&lt;span class="nt"&gt;eea&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;#764&lt;/span&gt;&lt;span class="nt"&gt;ba2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c"&gt;/* Circle in top-left corner */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt; &lt;span class="nt"&gt;at&lt;/span&gt; &lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nf"&gt;#ffecd2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;#fcb69f&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c"&gt;/* Closest-side sizing */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt; &lt;span class="nt"&gt;closest-side&lt;/span&gt; &lt;span class="nt"&gt;at&lt;/span&gt; &lt;span class="err"&gt;60&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;60&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;#a8edea&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;#fed6e3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Size keywords: &lt;code&gt;closest-side&lt;/code&gt;, &lt;code&gt;closest-corner&lt;/code&gt;, &lt;code&gt;farthest-side&lt;/code&gt;, &lt;code&gt;farthest-corner&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Conic Gradient
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;conic-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="nt"&gt;angle&lt;/span&gt; &lt;span class="nt"&gt;at&lt;/span&gt; &lt;span class="nt"&gt;position&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;color-stops&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good for pie charts, colour wheels, and angular patterns:&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="c"&gt;/* Pie chart: 30% red, 50% blue, 20% green */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;conic-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;red&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;30&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nt"&gt;blue&lt;/span&gt; &lt;span class="err"&gt;30&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;80&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nt"&gt;green&lt;/span&gt; &lt;span class="err"&gt;80&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%);&lt;/span&gt;

&lt;span class="c"&gt;/* Colour wheel */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;conic-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;red&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;lime&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;aqua&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;magenta&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;red&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Colour Stops — The Tricky Part
&lt;/h2&gt;

&lt;p&gt;You can position stops precisely using px, %, or viewport units:&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="c"&gt;/* Hard stop (no fade) */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="nt"&gt;right&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
  &lt;span class="err"&gt;#2&lt;/span&gt;&lt;span class="nt"&gt;f855a&lt;/span&gt; &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; 
  &lt;span class="err"&gt;#68&lt;/span&gt;&lt;span class="nt"&gt;d391&lt;/span&gt; &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c"&gt;/* Multi-stop with precise positions */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="nt"&gt;right&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nf"&gt;#f6d365&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nf"&gt;#fda085&lt;/span&gt; &lt;span class="err"&gt;80&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nf"&gt;#f093fb&lt;/span&gt; &lt;span class="err"&gt;200&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c"&gt;/* Hint: control the midpoint of the blend */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="nt"&gt;right&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;#2&lt;/span&gt;&lt;span class="nt"&gt;f855a&lt;/span&gt; &lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;40&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;#68&lt;/span&gt;&lt;span class="nt"&gt;d391&lt;/span&gt; &lt;span class="err"&gt;80&lt;/span&gt;&lt;span class="o"&gt;%);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Repeating Gradients
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Stripes */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;repeating-linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="err"&gt;45&lt;/span&gt;&lt;span class="nt"&gt;deg&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nt"&gt;transparent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nt"&gt;transparent&lt;/span&gt; &lt;span class="err"&gt;10&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="err"&gt;#2&lt;/span&gt;&lt;span class="nt"&gt;f855a&lt;/span&gt; &lt;span class="err"&gt;10&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="err"&gt;#2&lt;/span&gt;&lt;span class="nt"&gt;f855a&lt;/span&gt; &lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c"&gt;/* Rings */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;repeating-radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="nt"&gt;circle&lt;/span&gt; &lt;span class="nt"&gt;at&lt;/span&gt; &lt;span class="nt"&gt;center&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nt"&gt;transparent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nt"&gt;transparent&lt;/span&gt; &lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="err"&gt;#667&lt;/span&gt;&lt;span class="nt"&gt;eea&lt;/span&gt; &lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="err"&gt;#667&lt;/span&gt;&lt;span class="nt"&gt;eea&lt;/span&gt; &lt;span class="err"&gt;21&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Common Patterns in Real Projects
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use case&lt;/th&gt;
&lt;th&gt;Gradient type&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hero background&lt;/td&gt;
&lt;td&gt;Linear, 135deg&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#667eea → #764ba2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Card overlay&lt;/td&gt;
&lt;td&gt;Linear, to bottom&lt;/td&gt;
&lt;td&gt;&lt;code&gt;transparent → rgba(0,0,0,0.6)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Progress bar&lt;/td&gt;
&lt;td&gt;Linear, to right&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#2f855a → #68d391&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Radial spotlight&lt;/td&gt;
&lt;td&gt;Radial circle&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rgba(255,255,255,0.3) → transparent&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pie chart&lt;/td&gt;
&lt;td&gt;Conic&lt;/td&gt;
&lt;td&gt;&lt;code&gt;red 30%, blue 30%&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diagonal stripe&lt;/td&gt;
&lt;td&gt;Repeating linear&lt;/td&gt;
&lt;td&gt;45deg transparent/colour pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Browser Support
&lt;/h2&gt;

&lt;p&gt;All three gradient types (&lt;code&gt;linear-gradient&lt;/code&gt;, &lt;code&gt;radial-gradient&lt;/code&gt;, &lt;code&gt;conic-gradient&lt;/code&gt;) are supported in all modern browsers. Conic gradients are the newest — they've been in Chrome since 69, Firefox since 83, and Safari since 12.1.&lt;/p&gt;

&lt;p&gt;No prefixes needed in 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate Without the Maths
&lt;/h2&gt;

&lt;p&gt;If you'd rather see the result than work out the syntax, the &lt;strong&gt;&lt;a href="https://snappytools.app/gradient-generator/" rel="noopener noreferrer"&gt;SnappyTools Gradient Generator&lt;/a&gt;&lt;/strong&gt; lets you pick colours, adjust the angle, and copy the CSS directly. Supports linear and radial, with live preview on a real element.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What gradient patterns do you use most? Linear hero overlays, or do you actually use conic gradients in prod?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Readability Scores Explained: Flesch-Kincaid, Gunning Fog, and When They Actually Matter</title>
      <dc:creator>Snappy Tools</dc:creator>
      <pubDate>Thu, 04 Jun 2026 10:03:49 +0000</pubDate>
      <link>https://dev.to/snappy_tools/readability-scores-explained-flesch-kincaid-gunning-fog-and-when-they-actually-matter-74g</link>
      <guid>https://dev.to/snappy_tools/readability-scores-explained-flesch-kincaid-gunning-fog-and-when-they-actually-matter-74g</guid>
      <description>&lt;p&gt;If you've ever pasted text into a readability checker and gotten back a number you didn't know how to interpret, you're not alone. Readability scores are useful — but only if you understand what they're measuring and what they're not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Two Most Common Scores
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Flesch-Kincaid Reading Ease&lt;/strong&gt; (0–100 scale)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;90–100: Very easy (5th grade)&lt;/li&gt;
&lt;li&gt;70–80: Easy (6th grade)&lt;/li&gt;
&lt;li&gt;60–70: Standard (7th–8th grade)&lt;/li&gt;
&lt;li&gt;50–60: Fairly difficult (high school)&lt;/li&gt;
&lt;li&gt;30–50: Difficult (college level)&lt;/li&gt;
&lt;li&gt;0–30: Very confusing (professional)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Higher is easier. Most web content should aim for 60–70.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gunning Fog Index&lt;/strong&gt; (grade level)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Counts words with 3+ syllables as "complex"&lt;/li&gt;
&lt;li&gt;A score of 12 means 12th-grade reading level&lt;/li&gt;
&lt;li&gt;Aim for 8–10 for general web audiences&lt;/li&gt;
&lt;li&gt;Technical docs can go higher; marketing copy should go lower&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What These Scores Actually Measure
&lt;/h2&gt;

&lt;p&gt;Both metrics are based on two things only:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sentence length (longer = harder)&lt;/li&gt;
&lt;li&gt;Word complexity (longer/more syllables = harder)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;They do &lt;strong&gt;not&lt;/strong&gt; measure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether your logic is clear&lt;/li&gt;
&lt;li&gt;Whether your structure makes sense&lt;/li&gt;
&lt;li&gt;Whether the vocabulary is actually appropriate for the topic&lt;/li&gt;
&lt;li&gt;Jargon that's short but highly domain-specific&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A sentence like "Set &lt;code&gt;NODE_ENV=prod&lt;/code&gt; then run &lt;code&gt;npm ci&lt;/code&gt;" would score as "very easy" because the words are short — but it's meaningless to someone who doesn't know Node.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Readability Scores Help
&lt;/h2&gt;

&lt;p&gt;Use them as a signal, not a verdict:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Content marketing and landing pages:&lt;/strong&gt; Aim for Flesch 65+. Short sentences, short words. If your score is below 50, you're probably writing for yourself, not your reader.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technical documentation:&lt;/strong&gt; Aim for Flesch 50–65. You can't avoid technical terms, but you can keep surrounding sentences short. Fog Index 10–12 is fine here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Legal or financial writing:&lt;/strong&gt; Don't fight the score — add a plain-language summary at the top instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Email copy:&lt;/strong&gt; Flesch 70+ almost always performs better. Remove adjectives. Shorten paragraphs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Fixes That Actually Work
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Long sentences&lt;/td&gt;
&lt;td&gt;Split at conjunctions (and, but, so, because)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Passive voice&lt;/td&gt;
&lt;td&gt;Find "was/were/been + verb" and invert&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Noun stacking&lt;/td&gt;
&lt;td&gt;"the configuration file update process" → "updating the config"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Abstract nouns&lt;/td&gt;
&lt;td&gt;"utilisation" → "use"; "implementation" → "build"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hedging&lt;/td&gt;
&lt;td&gt;Remove "somewhat", "fairly", "quite"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Real Goal: Cognitive Load
&lt;/h2&gt;

&lt;p&gt;Readability scores are a proxy for cognitive load — the mental effort required to process a sentence. Lower cognitive load means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The reader can focus on the ideas, not the words&lt;/li&gt;
&lt;li&gt;They're less likely to re-read&lt;/li&gt;
&lt;li&gt;They finish more of the piece&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For web content, that translates directly to: lower bounce rate, more scroll depth, more conversions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check Your Content
&lt;/h2&gt;

&lt;p&gt;Paste any text into the &lt;strong&gt;&lt;a href="https://snappytools.app/readability-checker/" rel="noopener noreferrer"&gt;SnappyTools Readability Checker&lt;/a&gt;&lt;/strong&gt; to get Flesch-Kincaid, Gunning Fog, reading time, sentence length distribution, and keyword density — all in one pass, no account needed.&lt;/p&gt;

&lt;p&gt;The output shows you exactly which sentences are dragging your score down, so you can fix them surgically rather than rewriting everything.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's the hardest thing you've had to make readable? Drop it in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>writing</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
