<?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: George Adamson</title>
    <description>The latest articles on DEV Community by George Adamson (@georgeadamson).</description>
    <link>https://dev.to/georgeadamson</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%2F833211%2Fd57d0105-62a9-4a04-9740-57158248cb8c.jpeg</url>
      <title>DEV Community: George Adamson</title>
      <link>https://dev.to/georgeadamson</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/georgeadamson"/>
    <language>en</language>
    <item>
      <title>Numeric comparison in CSS (for conditional logic)</title>
      <dc:creator>George Adamson</dc:creator>
      <pubDate>Fri, 23 May 2025 15:56:24 +0000</pubDate>
      <link>https://dev.to/georgeadamson/numeric-comparison-in-css-4mbj</link>
      <guid>https://dev.to/georgeadamson/numeric-comparison-in-css-4mbj</guid>
      <description>&lt;p&gt;Conditional logic in CSS is tantalisingly close.&lt;/p&gt;

&lt;p&gt;Until CSS supports &lt;code&gt;if()&lt;/code&gt; and &lt;code&gt;else&lt;/code&gt; then we have to make do with workarounds.&lt;/p&gt;

&lt;p&gt;Others, such as &lt;a href="https://lea.verou.me/blog/2024/css-conditionals-now/" rel="noopener noreferrer"&gt;Lea Verou&lt;/a&gt;, have written superb guides about using binary logic to perform conditionals in CSS, using CSS Variables with values of &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Often however, we have ranges or numbers other than 0 or 1 in our CSS Variables so it would be handy if we could &lt;strong&gt;compare numeric values&lt;/strong&gt; and drive logic from them.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;TLDR&lt;/em&gt;: We can test for &lt;strong&gt;equality&lt;/strong&gt;, &lt;strong&gt;less-than&lt;/strong&gt; and &lt;strong&gt;greater-than&lt;/strong&gt; by using a combination of &lt;code&gt;calc()&lt;/code&gt;, &lt;code&gt;abs()&lt;/code&gt; and &lt;code&gt;sign()&lt;/code&gt; to give you a "boolean" value of &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When you have &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt; in a variable you can do conditional styles like &lt;code&gt;padding: calc(25px * var(--bool) + 10px * (1 - var(--bool)))&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In JS we might simply write:&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Apply some styles&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Apply some styles&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...but the best we could hope for in CSS right now is to set boolean variables like the following, and to use them in &lt;a href="https://lea.verou.me/blog/2024/css-conditionals-now/#binary-linear-interpolation" rel="noopener noreferrer"&gt;Binary Linear Interpolation&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;--isEqual&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="c"&gt;/* Some magical logic here */&lt;/span&gt;
&lt;span class="nt"&gt;--isGreaterThan&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="c"&gt;/* Some other magical logic */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well there is a way using &lt;code&gt;calc()&lt;/code&gt;, and the more recent &lt;code&gt;abs()&lt;/code&gt; and &lt;code&gt;sign()&lt;/code&gt;, to compare numbers and return &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Like this...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="na"&gt;--isNotEqual&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;))));&lt;/span&gt;
&lt;span class="na"&gt;--isEqual&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;isNotEqual&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="na"&gt;--isLessThan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;))));&lt;/span&gt;
&lt;span class="na"&gt;--isGreaterThan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;))));&lt;/span&gt;

&lt;span class="na"&gt;--isLessThanOrEqual&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;isGreaterThan&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="na"&gt;--isGreaterThanOrEqual&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;isLessThan&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="cm"&gt;/* I'd welcome any suggestions for smarter ways to derive these! */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://codepen.io/georgeadamson/pen/WbveKKP" rel="noopener noreferrer"&gt;Demo on CodePen&lt;/a&gt;, with fallbacks.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: &lt;code&gt;abs()&lt;/code&gt; and &lt;code&gt;sign()&lt;/code&gt; have only &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/abs#browser_compatibility" rel="noopener noreferrer"&gt;partial browser support&lt;/a&gt; but &lt;a href="https://dev.to/georgeadamson/polyfill-for-css-sign-2019"&gt;they can be achieved using older syntax&lt;/a&gt;. At time of writing only Safari &amp;amp; Firefox supported them.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>css</category>
      <category>conditional</category>
      <category>logic</category>
      <category>compare</category>
    </item>
    <item>
      <title>Polyfill for CSS sign() and abs()</title>
      <dc:creator>George Adamson</dc:creator>
      <pubDate>Fri, 23 May 2025 12:10:30 +0000</pubDate>
      <link>https://dev.to/georgeadamson/polyfill-for-css-sign-2019</link>
      <guid>https://dev.to/georgeadamson/polyfill-for-css-sign-2019</guid>
      <description>&lt;h2&gt;
  
  
  sign()
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/sign" rel="noopener noreferrer"&gt;CSS sign()&lt;/a&gt; is not well supported but can be "polyfilled" with &lt;code&gt;calc()&lt;/code&gt; &amp;amp; &lt;code&gt;clamp()&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Given...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  --input: 10; /* &amp;lt;-- Any number */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...then &lt;code&gt;sign()&lt;/code&gt; can be calculated using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  --num: calc(var(--input) * infinity); 
  --sign: clamp(-1, var(--num), 1);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above is equivalent to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  --sign: sign(var(--input));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Handy if you're attempting conditional logic and you need &lt;code&gt;0&lt;/code&gt;'s and &lt;code&gt;1&lt;/code&gt;'s instead of numbers. (What? Why? Read more about &lt;a href="https://lea.verou.me/blog/2024/css-conditionals-now/#binary-linear-interpolation" rel="noopener noreferrer"&gt;Binary Linear Interpolation&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;How it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Multiply by infinity to give us 0 or +/-infinity to avoid rounding errors when dealing with very small decimals. Tip: If you know your input numbers will never be between -1 &amp;amp; 1 then you can skip the &lt;code&gt;calc()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Round to the nearest &lt;code&gt;-1&lt;/code&gt;, &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://codepen.io/georgeadamson/pen/dPPqgXb" rel="noopener noreferrer"&gt;Demo on CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  abs()
&lt;/h2&gt;

&lt;p&gt;If you also need &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/abs" rel="noopener noreferrer"&gt;CSS abs(n)&lt;/a&gt; then simply use &lt;code&gt;sqrt(pow(n,2))&lt;/code&gt; instead: &lt;a href="https://codepen.io/georgeadamson/pen/Wbveyad" rel="noopener noreferrer"&gt;Demo on CodePen&lt;/a&gt;.&lt;br&gt;
Combined with &lt;code&gt;sign()&lt;/code&gt; you can derive "truthy" &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt; from any number.&lt;/p&gt;

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