<?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: Koushik Radhakrishnan</title>
    <description>The latest articles on DEV Community by Koushik Radhakrishnan (@koushikr).</description>
    <link>https://dev.to/koushikr</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3513369%2Fd68b975a-84df-4fa6-b971-cc52cc6a5aba.jpg</url>
      <title>DEV Community: Koushik Radhakrishnan</title>
      <link>https://dev.to/koushikr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/koushikr"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Koushik Radhakrishnan</dc:creator>
      <pubDate>Tue, 09 Jun 2026 07:17:13 +0000</pubDate>
      <link>https://dev.to/koushikr/-23g8</link>
      <guid>https://dev.to/koushikr/-23g8</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/koushikr/your-ai-code-reviewer-is-a-liar-and-youre-making-it-worse-h75" class="crayons-story__hidden-navigation-link"&gt;Your AI Code Reviewer Is a Liar, And You're Making It Worse&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/koushikr" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3513369%2Fd68b975a-84df-4fa6-b971-cc52cc6a5aba.jpg" alt="koushikr profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/koushikr" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Koushik Radhakrishnan
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Koushik Radhakrishnan
                
              
              &lt;div id="story-author-preview-content-3854318" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/koushikr" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3513369%2Fd68b975a-84df-4fa6-b971-cc52cc6a5aba.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Koushik Radhakrishnan&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/koushikr/your-ai-code-reviewer-is-a-liar-and-youre-making-it-worse-h75" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 9&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/koushikr/your-ai-code-reviewer-is-a-liar-and-youre-making-it-worse-h75" id="article-link-3854318"&gt;
          Your AI Code Reviewer Is a Liar, And You're Making It Worse
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/codereview"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;codereview&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devtools"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devtools&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/koushikr/your-ai-code-reviewer-is-a-liar-and-youre-making-it-worse-h75#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              2&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Your AI Code Reviewer Is a Liar, And You're Making It Worse</title>
      <dc:creator>Koushik Radhakrishnan</dc:creator>
      <pubDate>Tue, 09 Jun 2026 07:12:44 +0000</pubDate>
      <link>https://dev.to/koushikr/your-ai-code-reviewer-is-a-liar-and-youre-making-it-worse-h75</link>
      <guid>https://dev.to/koushikr/your-ai-code-reviewer-is-a-liar-and-youre-making-it-worse-h75</guid>
      <description>&lt;p&gt;You asked AI to review your legacy codebase.&lt;br&gt;
It came back with a thorough, confident breakdown. Deprecated patterns. Security concerns. Architectural red flags. You felt seen.&lt;br&gt;
Then you pushed back on one finding.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Are you sure? This pattern has been in production for three years without issues."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the AI said something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"You raise a fair point. Given the production stability you mention, this may not be a critical issue after all."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So you pushed again. Different finding.&lt;br&gt;
Same story.&lt;/p&gt;

&lt;p&gt;By the end of the session, every concern you challenged had softened, dissolved, or been reframed as "a valid tradeoff." The confident reviewer from ten minutes ago had become your hype man.&lt;/p&gt;

&lt;p&gt;You weren't getting a code review anymore. You were getting a mirror.&lt;/p&gt;




&lt;h3&gt;
  
  
  This Has a Name
&lt;/h3&gt;

&lt;p&gt;What you just experienced is called &lt;strong&gt;&lt;em&gt;AI sycophancy&lt;/em&gt;&lt;/strong&gt; — and it's one of the most dangerous failure modes you can hit when using LLMs for anything that requires an adversarial stance.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sycophancy isn't a bug. It's a learned behavior. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;During RLHF training (reinforcement learning from human feedback), the model is rated by humans on how good its responses are. And humans — being humans — tend to rate agreeable, validating responses higher. Not always consciously. But consistently enough that the model learns a subtle, deeply embedded lesson over millions of iterations: &lt;strong&gt;People prefer to be agreed with.&lt;/strong&gt; So the model optimises for that. It doesn't lie to you in the way a bad colleague lies. It just... lacks conviction. The moment you express confidence in a position, it recalibrates toward yours. It confuses your certainty with correctness.&lt;br&gt;
For creative brainstorming? Mildly annoying.&lt;br&gt;
For code review of a system that runs in production? Actively dangerous.&lt;/p&gt;




&lt;h3&gt;
  
  
  Why Code Review Gets Hit Hardest
&lt;/h3&gt;

&lt;p&gt;A good human code reviewer does one thing above all else: they hold the line.&lt;/p&gt;

&lt;p&gt;When you say "this has worked fine for years," they say "then let's understand why it works, because it shouldn't." When you say "I'll fix it later," they say "that's what the last four devs said." They don't capitulate under social pressure. Their job is to be right, not agreeable. AI sycophancy dismantles exactly this. Here's how it plays out in the wild:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The confidence flip&lt;/strong&gt;&lt;br&gt;
AI flags a potential race condition. You say it's intentional. AI says "that's a reasonable approach." The original flag was correct — the AI just didn't fight for it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The moving goalpost&lt;/strong&gt;&lt;br&gt;
AI finds five security issues. You explain away three with context. AI absorbs your narrative and quietly downgrades the remaining two. You're now shaping the review from inside the review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The false balance&lt;/strong&gt;&lt;br&gt;
You push hard enough and the AI retreats to "both approaches are valid depending on your use case." This sounds measured. It's usually just the AI failing to tell you you're wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The authority trap&lt;/strong&gt;&lt;br&gt;
You say "I've been on this codebase for four years." The AI weights your tenure as credibility — even though being the longest-surviving author of a mess doesn't make the mess correct.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Real Problem: You're Reviewing the Reviewer
&lt;/h3&gt;

&lt;p&gt;Here's the uncomfortable truth: the moment you start evaluating whether the AI's findings are accurate, you're doing the review yourself.&lt;/p&gt;

&lt;p&gt;The AI hasn't saved you work. It's restructured it — and added a new, insidious layer. Now you have to expend mental energy figuring out which confident-sounding outputs to trust. And the more you engage with it, the more your assumptions contaminate its conclusions.&lt;br&gt;
This is especially brutal with legacy code. Legacy codebases are full of intentional weirdness — patterns that look wrong but exist for a reason. Ancient library workarounds. Timeout values that were calibrated against a vendor API that no longer even exists. Performance hacks that violate every modern convention but have the scars to prove themselves.&lt;/p&gt;

&lt;p&gt;The AI has zero memory of why these decisions were made. You do. So the conversation becomes you explaining the codebase to the AI. And the AI adjusts its review based on what you tell it.&lt;br&gt;
Which means by the end, the review reflects your assumptions — not an independent assessment.&lt;/p&gt;




&lt;h3&gt;
  
  
  How to Actually Fix This
&lt;/h3&gt;

&lt;p&gt;The good news: sycophancy is a known, documented problem with known mitigations. Here's what actually works.&lt;/p&gt;

&lt;p&gt;🧊 1. Run a Cold Review First — Zero Context&lt;br&gt;
Your single most impactful change.&lt;br&gt;
Paste the code with no framing. No "I think this is fine, but—". No explanation of what it does. No architectural context. Just:&lt;br&gt;
Review this code. List every concern, large and small, with a severity rating. Do not ask clarifying questions — flag anything that looks potentially problematic.&lt;br&gt;
Save this output verbatim. This is your ground truth. Everything after this point is commentary.&lt;/p&gt;

&lt;p&gt;🥊 2. Challenge After, Not During&lt;br&gt;
Never push back in the same session as the review. Open a fresh conversation, paste the saved review output, and challenge findings one at a time.&lt;br&gt;
Why? Because in a fresh session, the AI has no emotional investment in its prior answers. It didn't "write" those findings — it's reading them like you are. This breaks the confirmation loop.&lt;/p&gt;

&lt;p&gt;🏋️ 3. Ask for the Steelman, Not the Retraction&lt;br&gt;
When you want to challenge a finding, don't ask:&lt;/p&gt;

&lt;p&gt;❌ "Is this actually a problem? Our team has been doing this for years."&lt;/p&gt;

&lt;p&gt;Ask instead:&lt;/p&gt;

&lt;p&gt;✅ "Assume I'm wrong to dismiss this finding. What's the strongest case that it IS a real problem, even given what I just told you?"&lt;/p&gt;

&lt;p&gt;This forces the AI to hold both perspectives simultaneously, instead of just capitulating to yours.&lt;/p&gt;

&lt;p&gt;🔍 4. Request Confidence Ratings&lt;br&gt;
Ask the AI to attach a confidence score (1–5) to each finding, along with what would change its assessment.&lt;br&gt;
A finding rated 2/5 with "this is a common pattern and may be intentional" is very different from a 5/5 with "this will cause a deadlock under concurrent writes." Now you know where to spend your skepticism — and where to actually trust the output.&lt;/p&gt;

&lt;p&gt;🪞 5. Treat Agreement as a Yellow Flag&lt;br&gt;
If you challenged five findings and the AI reversed on all five — that's not you being right five times.&lt;br&gt;
That's the model failing to hold its ground.&lt;br&gt;
A useful heuristic: if the AI agrees with everything you say, something is wrong. Count the reversals. More than two or three in a session and you've likely entered a sycophancy spiral.&lt;/p&gt;

&lt;p&gt;🔁 6. Run Multiple Independent Passes&lt;br&gt;
Different prompt angles, fresh sessions:&lt;/p&gt;

&lt;p&gt;Pass 1: Security lens&lt;br&gt;
Pass 2: Performance lens&lt;br&gt;
Pass 3: Maintainability and tech debt lens&lt;/p&gt;

&lt;p&gt;Compare where concerns overlap across passes. Consensus across independent runs is far more trustworthy than any single review — because each pass has no knowledge of what the others found.&lt;/p&gt;




&lt;h3&gt;
  
  
  A Workflow That Accounts for Sycophancy
&lt;/h3&gt;

&lt;p&gt;Here's the full structure I now use:&lt;/p&gt;

&lt;p&gt;Phase 1 — Cold Review&lt;br&gt;
  └─ Fresh session. No context. Just code.&lt;br&gt;
  └─ "List all concerns with severity ratings."&lt;br&gt;
  └─ Save output. Don't touch it.&lt;/p&gt;

&lt;p&gt;Phase 2 — Controlled Context Injection&lt;br&gt;&lt;br&gt;
  └─ New session. Paste saved findings.&lt;br&gt;
  └─ Add one piece of context at a time.&lt;br&gt;
  └─ Ask: "Does this context change finding X? Why?"&lt;br&gt;
  └─ Track which findings shift and the reason.&lt;/p&gt;

&lt;p&gt;Phase 3 — Adversarial Pass&lt;br&gt;
  └─ For every finding you want to dismiss:&lt;br&gt;
  └─ "Assume I'm wrong. Worst realistic outcome if this concern is valid?"&lt;/p&gt;

&lt;p&gt;Phase 4 — Human Decision&lt;br&gt;
  └─ AI informs. You decide.&lt;br&gt;
  └─ The AI has no memory of why things are the way they are.&lt;br&gt;
  └─ You do. Own that.&lt;/p&gt;




&lt;h3&gt;
  
  
  The bottom line:
&lt;/h3&gt;

&lt;p&gt;AI is not a replacement for a senior engineer who's seen your specific failure modes and won't back down in a code review. It's a powerful first pass — but only if you protect the independence of that first pass. The moment you start negotiating with it, the review is over.&lt;/p&gt;




&lt;p&gt;What's your workaround when AI stops pushing back? Cold reviews, steelmanning, something I haven't thought of — drop it in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>codereview</category>
      <category>programming</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Sass isn't dead, but native CSS just replaced its biggest use case. We can finally write reusable, type-safe functions directly in the browser, with zero build tools. I wrote up a practical guide on Dev.to explaining exactly how native `@function` works.</title>
      <dc:creator>Koushik Radhakrishnan</dc:creator>
      <pubDate>Sun, 31 May 2026 06:24:26 +0000</pubDate>
      <link>https://dev.to/koushikr/sass-isnt-dead-but-native-css-just-replaced-its-biggest-use-case-we-can-finally-write-reusable-li1</link>
      <guid>https://dev.to/koushikr/sass-isnt-dead-but-native-css-just-replaced-its-biggest-use-case-we-can-finally-write-reusable-li1</guid>
      <description>&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://dev.to/koushikr/css-function-1a39" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe7f0rkiyb9skynogotdv.png" height="auto" class="m-0"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://dev.to/koushikr/css-function-1a39" rel="noopener noreferrer" class="c-link"&gt;
            CSS @function - DEV Community
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            CSS just got its biggest quality-of-life upgrade since custom properties.   For years, if you wanted...
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png"&gt;
          dev.to
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>css</category>
      <category>frontend</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>CSS @function</title>
      <dc:creator>Koushik Radhakrishnan</dc:creator>
      <pubDate>Sun, 31 May 2026 06:15:04 +0000</pubDate>
      <link>https://dev.to/koushikr/css-function-1a39</link>
      <guid>https://dev.to/koushikr/css-function-1a39</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;CSS just got its biggest quality-of-life upgrade since custom properties.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For years, if you wanted reusable logic in CSS, you had two choices: wrestle with custom properties that couldn't do real computation, or reach for a preprocessor like Sass. That era just quietly ended. CSS now has native custom functions — and they're as powerful as you'd hope.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. What Exactly Is &lt;code&gt;@function&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Think of it exactly like a JavaScript function — but living inside your stylesheet. You give it a name (always prefixed with &lt;code&gt;--&lt;/code&gt;), define some parameters, and write a &lt;code&gt;result:&lt;/code&gt; descriptor that determines what it returns.&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;/* BASIC SYNTAX */&lt;/span&gt;

&lt;span class="c"&gt;/* Define it once */&lt;/span&gt;
&lt;span class="k"&gt;@function&lt;/span&gt; &lt;span class="n"&gt;--double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&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;--x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Call it anywhere */&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;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c"&gt;/* → 40px */&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;/* → 100px */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;var()&lt;/code&gt; wrapper needed to call it. No build step. No Sass import. Just define and use — as many times as you like, across your entire stylesheet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Unlike Sass, native CSS functions don't evaluate math automatically. You must wrap mathematical operations in calc() inside your result descriptor.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  2. The Syntax in Full Detail
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Parameters with Default Values
&lt;/h3&gt;

&lt;p&gt;You can make parameters optional by giving them a fallback — the function still works even if you don't pass a value.&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;@function&lt;/span&gt; &lt;span class="n"&gt;--spacing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&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;--size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--spacing&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;      &lt;span class="c"&gt;/* → 24px (uses default) */&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--spacing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c"&gt;/* → 30px */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Type-Safe Parameters
&lt;/h3&gt;

&lt;p&gt;You can declare the expected type of each parameter — and the return type too. The browser will validate this at parse time, preventing weird cascading bugs.&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;@function&lt;/span&gt; &lt;span class="n"&gt;--fade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;--color&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;--alpha&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;color-mix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;srgb&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&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nb"&gt;transparent&lt;/span&gt; &lt;span class="n"&gt;calc&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;--alpha&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.overlay&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;--fade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;royalblue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;/* 70% opaque blue */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Logic Inside Functions
&lt;/h3&gt;

&lt;p&gt;This is where &lt;code&gt;@function&lt;/code&gt; gets genuinely exciting. You can embed &lt;code&gt;@media&lt;/code&gt; or &lt;code&gt;@supports&lt;/code&gt; queries right inside a function to return different values based on conditions.&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;@function&lt;/span&gt; &lt;span class="n"&gt;--responsive-font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--sm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;--lg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;result&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;--sm&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;/* mobile default */&lt;/span&gt;

  &lt;span class="err"&gt;@media&lt;/span&gt; &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;768px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;result&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;--lg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;/* larger screen override */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--responsive-font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;48px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;p&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--responsive-font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;18px&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;h2&gt;
  
  
  3. Real-World Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Example 1 — Theme-Aware Sizing (Light/Dark)
&lt;/h3&gt;

&lt;p&gt;The built-in &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/color_value/light-dark" rel="noopener noreferrer"&gt;light-dark()&lt;/a&gt; function only works with color values. With &lt;code&gt;@function&lt;/code&gt;, you can extend that same idea to any CSS property — font weights, border radius, letter spacing, anything.&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;@function&lt;/span&gt; &lt;span class="n"&gt;--theme-val&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--light&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;--dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;result&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;--light&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="err"&gt;@media&lt;/span&gt; &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="py"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;result&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;--dark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--theme-val&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&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;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--theme-val&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;letter-spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--theme-val&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0em&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.03em&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;h3&gt;
  
  
  Example 2 — Color Opacity Shorthand
&lt;/h3&gt;

&lt;p&gt;Stop writing &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/color_value/color-mix" rel="noopener noreferrer"&gt;color-mix()&lt;/a&gt; from scratch every time you need a translucent variant of a color.&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;@function&lt;/span&gt; &lt;span class="n"&gt;--alpha&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;--c&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;--a&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;color-mix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;srgb&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;--c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;calc&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;--a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nb"&gt;transparent&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.modal-bg&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;--alpha&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;#0f0f0f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.chip&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;--alpha&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;royalblue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.15&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.highlight&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;--alpha&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;gold&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.3&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;h2&gt;
  
  
  4. Why This Beats Sass/SCSS for These Use Cases?
&lt;/h2&gt;

&lt;p&gt;Let's be clear — Sass isn't going away. But &lt;code&gt;@function&lt;/code&gt; directly replaces its most common use case: reusable value computation. Here's why the native approach wins:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No build step.&lt;/strong&gt; Your function evaluates at runtime in the browser, not at compile time. It can react to live conditions like viewport size or user preferences.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Works with custom properties.&lt;/strong&gt; You can pass &lt;code&gt;var(--token)&lt;/code&gt; directly as a function argument. Sass couldn't dynamically read runtime custom property values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type safety.&lt;/strong&gt; Declare parameter types and return types. The browser validates them — something Sass never did natively.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ships in your CSS.&lt;/strong&gt; Devtools can inspect it, browser can cache it. Zero toolchain friction.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Browser Support &amp;amp; Current Limitations
&lt;/h2&gt;

&lt;p&gt;🔴 &lt;code&gt;@function&lt;/code&gt; shipped in Chrome 139 (May 2025) and is supported across Chrome, Edge, and Opera (~67% of global users). Firefox and Safari are still pending — production use without a fallback affects ~33% of users.&lt;/p&gt;

&lt;p&gt;🚫 No recursion. A function cannot call itself. Recursive patterns need to stay in JavaScript.&lt;/p&gt;

&lt;p&gt;🚫 No side effects. Functions can only compute and return a value. You can't modify a DOM element's class or trigger an animation directly from inside a function.&lt;/p&gt;

&lt;p&gt;⚠️ Name must start with &lt;code&gt;--&lt;/code&gt;. Easy to forget. &lt;code&gt;--my-fn()&lt;/code&gt; works; &lt;code&gt;myFn()&lt;/code&gt; does not.&lt;/p&gt;

&lt;p&gt;⚠️ Spec is still evolving. Some details (like interaction with cascade layers) are still being refined in the &lt;code&gt;css-mixins-1&lt;/code&gt; spec. Treat this as stable-but-maturing.&lt;/p&gt;

&lt;p&gt;⚠️ No cross-file imports natively. Functions defined in one CSS file are not automatically available in another unless you use &lt;code&gt;@import&lt;/code&gt; or bundle them together.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Progressive Enhancement Strategy&lt;br&gt;
Use &lt;code&gt;@supports&lt;/code&gt; to check for &lt;code&gt;@function&lt;/code&gt; support, or define a plain &lt;code&gt;var()&lt;/code&gt; fallback first and layer your function-based values on top. Users on unsupported browsers will get the fallback; Chrome/Edge users get the enhanced version.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;If this was useful, share it with your frontend team. Drop a comment with the most creative use case you can think of — I'd love to see what people build with this. 👇&lt;/p&gt;

</description>
      <category>css</category>
      <category>styling</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
