<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Milanin</title>
    <description>The latest articles on Forem by Milanin (@milandev).</description>
    <link>https://forem.com/milandev</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%2F721013%2Ff8d0d63e-8c2a-4440-a8bb-740d72631d73.png</url>
      <title>Forem: Milanin</title>
      <link>https://forem.com/milandev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/milandev"/>
    <language>en</language>
    <item>
      <title>JavaScript Internationalization</title>
      <dc:creator>Milanin</dc:creator>
      <pubDate>Wed, 30 Nov 2022 20:49:52 +0000</pubDate>
      <link>https://forem.com/milandev/formatting-data-like-a-pro-in-javascript-332m</link>
      <guid>https://forem.com/milandev/formatting-data-like-a-pro-in-javascript-332m</guid>
      <description>&lt;p&gt;Formatting data in JavaScript might occasionally be challenging. I see improperly formatted data far too often. Did you know that JavaScript has a standardized built-in object designed just for that? I didn't either! &lt;br&gt;
&lt;code&gt;Intl&lt;/code&gt; is an object namespace for Internalization API, currently supported by &amp;gt;98% of all browsers! (as of December 2024)&lt;br&gt;
So what can we do with it? I am going to show you how to use &lt;code&gt;Intl&lt;/code&gt; to format units, plurals, and relative time. Aside from that, &lt;code&gt;Intl&lt;/code&gt; supports date formatting, but we have long-established libraries for that, as well as formatting lists, comparing the order of letters, and segmenting sentences, words, and graphemes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In this post I will cover:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Formatting units&lt;/li&gt;
&lt;li&gt;Plural-sensitive formatting&lt;/li&gt;
&lt;li&gt;Formatting relative time&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  What locales are supported?
&lt;/h3&gt;

&lt;p&gt;All &lt;code&gt;Intl&lt;/code&gt; functionality is heavily reliant on locale, but how can we determine which locales are supported? &lt;code&gt;Intl&lt;/code&gt; has got this covered with its &lt;code&gt;Intl.getCanonicalLocales(locales)&lt;/code&gt; function.&lt;br&gt;
It accepts either a string containing a locale code or an array of strings and returns an array of accurate names for supported locales.&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="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;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCanonicalLocales&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CS-CZ&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;If we don't know the exact code name and don't know if it's supported at all, we can pass it into the function, capitalized. And it will return an array of supported locales with correct capitalization. So the output for this code looks like this:&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="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cs-CZ&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;h2&gt;
  
  
  Formatting numbers
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Intl&lt;/code&gt; contains a &lt;code&gt;NumberFormat&lt;/code&gt; class which lets you format… numbers (&lt;em&gt;duh&lt;/em&gt;). To use &lt;code&gt;NumberFormat&lt;/code&gt; we must first create it, with the &lt;code&gt;locale&lt;/code&gt; that we need, and &lt;code&gt;options&lt;/code&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="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NumberFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More info about &lt;code&gt;Intl.NumberFormat()&lt;/code&gt; and its options &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules/PluralRules" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Formatting units
&lt;/h3&gt;

&lt;p&gt;The most important options for formatting units are &lt;code&gt;style&lt;/code&gt;, &lt;code&gt;unit&lt;/code&gt;, and &lt;code&gt;unitDisplay&lt;/code&gt;. What do they do?&lt;br&gt;
&lt;code&gt;style&lt;/code&gt; manages how we want to format our numbers, and it accepts "&lt;code&gt;decimal&lt;/code&gt;," "&lt;code&gt;currency&lt;/code&gt;", "&lt;code&gt;percent&lt;/code&gt;,"  or "&lt;code&gt;unit&lt;/code&gt;."  Since we want to format units, we’re going to set style to "unit."&lt;br&gt;
&lt;code&gt;unit&lt;/code&gt; means what kind of unit we want. All of the daily life units are supported by NumberFormat. You can find all of them here. Now let's go format some data.&lt;br&gt;
&lt;code&gt;unitDisplay&lt;/code&gt; tells if it should use the whole unit name or a short notation, e.g., kilogram for &lt;code&gt;long&lt;/code&gt;, kg for &lt;code&gt;short&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So let’s format kilogram units as an example. First,  we create options:&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;kilogramOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;unit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;kilogram&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;unitDisplay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;short&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;And create the NumberFormat instance:&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;kilogramFmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NumberFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-UK&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;kilogramOptions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally you can format the number that you need with the format function.&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;kilogramFmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’m passing &lt;code&gt;en-UK&lt;/code&gt; into &lt;code&gt;locale&lt;/code&gt;, but if you try passing &lt;code&gt;ru&lt;/code&gt;, you will see that it uses Cyrillic instead of the alphabet. If you try passing in &lt;code&gt;long&lt;/code&gt; to &lt;code&gt;unitDisplay&lt;/code&gt;, and &lt;code&gt;de&lt;/code&gt; as &lt;code&gt;locale&lt;/code&gt;, it will capitalize the K in Kilogram; if you change &lt;code&gt;locale&lt;/code&gt; to &lt;code&gt;cs&lt;/code&gt;, you will see it in Czech. So that’s perfect! It localizes the units in all languages. &lt;br&gt;
Now, how about we try plural-sensitive formatting next?&lt;/p&gt;
&lt;h2&gt;
  
  
  Plural-sensitive formatting
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Intl&lt;/code&gt; provides yet another class to solve this problem, &lt;code&gt;PluralRules&lt;/code&gt;. It lets us format cardinal and ordinal numbers. Quick explanation: Cardinal means: 1-one; 2-two; 3-three; and 4-four, and ordinal means: 1-first; 2-second; 3-third; and 4-fourth.&lt;br&gt;
This is exactly what we are going to be passing into options for the PluralRules constructor: type: cardinal or ordinal, which looks exactly the same as &lt;code&gt;NumberFormat&lt;/code&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="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PluralRules&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locales&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we create our &lt;code&gt;PluralRules&lt;/code&gt; formatter, here is an explaination on how it works. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When we pass a number into &lt;code&gt;PluralRules&lt;/code&gt; with the &lt;code&gt;cardinal&lt;/code&gt; type, it does not return "&lt;code&gt;one&lt;/code&gt;", "&lt;code&gt;two&lt;/code&gt;", "&lt;code&gt;three&lt;/code&gt;", or "&lt;code&gt;four&lt;/code&gt;", as I've mentioned before. It will return "&lt;code&gt;zero&lt;/code&gt;", "&lt;code&gt;one&lt;/code&gt;", "&lt;code&gt;two&lt;/code&gt;", "&lt;code&gt;few&lt;/code&gt;", "&lt;code&gt;many&lt;/code&gt;", or "&lt;code&gt;other&lt;/code&gt;", This is because instead of returning the exact value that we just passed in, it returns grammatical category of that number.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This depends on the locale that we use. With &lt;code&gt;en-UK&lt;/code&gt;, you will see only &lt;code&gt;one&lt;/code&gt; or &lt;code&gt;other&lt;/code&gt;. You can experiment with different numbers and locales to see what results you get. Then with &lt;code&gt;one&lt;/code&gt; … &lt;code&gt;other&lt;/code&gt; you can format your data the way you need. e.g., with &lt;code&gt;locale&lt;/code&gt; set to &lt;code&gt;en-UK&lt;/code&gt;, if we get &lt;code&gt;one&lt;/code&gt;, leave the word singular; if we get &lt;code&gt;other&lt;/code&gt; make the word plural.&lt;/p&gt;

&lt;p&gt;Now here comes the confusing part.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When we pass a number into PluralRules with the ordinal type... it returns the exact same values. Except this time it returns it as ordinal categories instead of cardinal. While with &lt;code&gt;en-UK&lt;/code&gt; &amp;amp; &lt;code&gt;ordinal&lt;/code&gt; we were getting only &lt;code&gt;one&lt;/code&gt; or &lt;code&gt;other&lt;/code&gt;, here we get "&lt;code&gt;one&lt;/code&gt;", "&lt;code&gt;two&lt;/code&gt;", "&lt;code&gt;few&lt;/code&gt;" or "&lt;code&gt;other&lt;/code&gt;".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can use these values now to format &lt;code&gt;-st&lt;/code&gt;, &lt;code&gt;-nd&lt;/code&gt;, &lt;code&gt;-rd&lt;/code&gt; and &lt;code&gt;-th&lt;/code&gt;. Which I very often see done incorrectly, and this is why I find this class, &lt;code&gt;PluralRules&lt;/code&gt;, helpful.&lt;/p&gt;

&lt;p&gt;First we create our ordinal formatter:&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;pluralFmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PluralRules&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ordinal&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;And now we can create our map for suffixes, and you will very quickly see how this class can be helpful for us.&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;suffixes&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;Map&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;one&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;st&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;few&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;other&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;th&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And last step is format our number and remap the suffix.&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;rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pluralFmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&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;suffix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;suffixes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;suffix&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we're done! We can now successfully format our numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Formatting relative time
&lt;/h3&gt;

&lt;p&gt;The last thing I want to cover in this blog (as it's getting quite long) is formatting relative time. Now, by saying this, I don't mean anything like formatting dates. I mean something way more useful. We've all downloaded a file from the internet at some point. When you click download, you will see a sign telling you "&lt;code&gt;15 minutes left&lt;/code&gt;" or something like this. This is exactly what we're going to do now!&lt;/p&gt;

&lt;p&gt;First, we create the &lt;code&gt;RelativeTimeFormat&lt;/code&gt; instance.&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;relativeTimeFmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RelativeTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For us right now, the most important options are: &lt;code&gt;numeric&lt;/code&gt; and &lt;code&gt;style&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;Numeric&lt;/code&gt; accepts &lt;code&gt;always&lt;/code&gt; or &lt;code&gt;auto&lt;/code&gt;. &lt;br&gt;
I recommend going with &lt;code&gt;always&lt;/code&gt;, since &lt;code&gt;auto&lt;/code&gt; could replace numbers with words, e.g., instead of "&lt;code&gt;1 day ago&lt;/code&gt;" it will say "&lt;code&gt;yesterday&lt;/code&gt;". This sounds like a good thing, but with some units other than days, it might be a problem, so keep it in mind.&lt;br&gt;
&lt;code&gt;Style&lt;/code&gt; accepts &lt;code&gt;short&lt;/code&gt;, &lt;code&gt;long&lt;/code&gt; and &lt;code&gt;narrow&lt;/code&gt;. &lt;code&gt;Short&lt;/code&gt; writes all units in shortened notation, and &lt;code&gt;long&lt;/code&gt; writes out the whole words, e.g., "&lt;code&gt;minute&lt;/code&gt;" for &lt;code&gt;long&lt;/code&gt; and "&lt;code&gt;min&lt;/code&gt;" for &lt;code&gt;short&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;Narrow&lt;/code&gt; is similar to "short" in some locales. This applies to the English locale.&lt;/p&gt;

&lt;p&gt;Once we have done that we can finally format our relative time.&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;relativeTimeFmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that input can be a negative number.&lt;br&gt;
Supported &lt;code&gt;unit&lt;/code&gt;s are: "&lt;code&gt;year&lt;/code&gt;", "&lt;code&gt;quarter&lt;/code&gt;", "&lt;code&gt;month&lt;/code&gt;", "&lt;code&gt;week&lt;/code&gt;", "&lt;code&gt;day&lt;/code&gt;", "&lt;code&gt;hour&lt;/code&gt;", "&lt;code&gt;minute&lt;/code&gt;", "&lt;code&gt;second&lt;/code&gt;".&lt;/p&gt;

&lt;p&gt;Congratulations! Now you know how to properly format data in JavaScript!&lt;br&gt;
This topic contains so much more information than I can possibly cover here. You can find all the examples used in this post &lt;a href="https://codepen.io/milansav/pen/oNyyKxy" rel="noopener noreferrer"&gt;here&lt;/a&gt;. And more about the &lt;code&gt;Intl&lt;/code&gt; namespace &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
And if you don't want to go through all the hassle of creating objects, you can just use a library. A perfect example is &lt;strong&gt;&lt;a href="https://formatjs.io/" rel="noopener noreferrer"&gt;Format.JS&lt;/a&gt;&lt;/strong&gt;, which is a library based on the &lt;code&gt;Intl&lt;/code&gt; namespace.&lt;br&gt;
Thank you for reading this all the way through.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>career</category>
      <category>discuss</category>
    </item>
    <item>
      <title>CSS @container query.</title>
      <dc:creator>Milanin</dc:creator>
      <pubDate>Sun, 27 Nov 2022 17:18:24 +0000</pubDate>
      <link>https://forem.com/milandev/make-your-websites-more-responsive-hf8</link>
      <guid>https://forem.com/milandev/make-your-websites-more-responsive-hf8</guid>
      <description>&lt;p&gt;We've all had to make our sites responsive at some point.&lt;br&gt;
Flexbox, grid, and &lt;a class="mentioned-user" href="https://dev.to/media"&gt;@media&lt;/a&gt; queries are pretty much the standard options for most of the developers out there.&lt;/p&gt;

&lt;p&gt;Some of you might have even had to change an element's style based on its container size using JavaScript. But did you know, you could avoid all that hassle with one css at-rule?&lt;/p&gt;

&lt;p&gt;Today I'm going to introduce you to the CSS &lt;code&gt;@container&lt;/code&gt; rule.&lt;/p&gt;

&lt;p&gt;This rule is very similar to the &lt;code&gt;@media&lt;/code&gt; rule, however, while &lt;code&gt;@media&lt;/code&gt; triggers style changes based on media properties, the &lt;code&gt;@container&lt;/code&gt; triggers style changes based on parent container properties.&lt;/p&gt;

&lt;p&gt;Where I see the opportunity to use this rule is in uncluttering or even removing content from small, cramped cards.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feip9zl0gsfzergl58rg4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feip9zl0gsfzergl58rg4.png" alt="Image description" width="651" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find this example &lt;a href="https://codepen.io/milansav/pen/WNyygbv" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The syntax for the &lt;code&gt;@container&lt;/code&gt; rule is the same as for the &lt;code&gt;@media&lt;/code&gt; rule.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@container &amp;lt;condition&amp;gt; {
  &amp;lt;style&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The condition supports the following descriptors: &lt;code&gt;aspect-ratio&lt;/code&gt;, &lt;code&gt;orientation&lt;/code&gt;, &lt;code&gt;block-size&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, &lt;code&gt;width&lt;/code&gt;, and &lt;code&gt;inline-size&lt;/code&gt;.&lt;br&gt;
Most of the descriptors speak for themselves, however, with &lt;code&gt;orientation&lt;/code&gt;, I want to mention, that it's not dependent on the orientation of your device, but rather on the aspect-ratio of the parent container, eg., if width is greater than height, the orientation is &lt;code&gt;landscape&lt;/code&gt; in the opposite case &lt;code&gt;portrait&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can combine multiple conditions with keywords like &lt;code&gt;and&lt;/code&gt;, &lt;code&gt;or&lt;/code&gt;, and &lt;code&gt;not&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;@container &amp;lt;cond&amp;gt; and &amp;lt;cond&amp;gt; or &amp;lt;cond&amp;gt; not &amp;lt;cond&amp;gt; {
  &amp;lt;styles&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Practical example of this could be:&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;@container&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;500px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&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;This means that &lt;code&gt;h2&lt;/code&gt;'s background color will be set to red when its parent container's &lt;code&gt;width&lt;/code&gt; is greater than 400 px and less than 500 px.&lt;/p&gt;

&lt;p&gt;Let's have a look at how you can define a container with some properties.&lt;/p&gt;

&lt;p&gt;Let's say we currently have an empty class &lt;code&gt;.container&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.container&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;You can specify the container's name and behavior with &lt;br&gt;
either the &lt;code&gt;container-name&lt;/code&gt; and &lt;code&gt;container-type&lt;/code&gt; properties. &lt;br&gt;
or &lt;code&gt;container: container-name / container-type&lt;/code&gt; (which hasn't worked for me for some reason but the long version works flawlessly!).&lt;/p&gt;

&lt;p&gt;Values available for &lt;code&gt;container-type&lt;/code&gt; are &lt;code&gt;size&lt;/code&gt;, &lt;code&gt;inline-size&lt;/code&gt;, and &lt;code&gt;normal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Container type &lt;code&gt;size&lt;/code&gt; lets you query a container's size in both block and inline dimensions, &lt;code&gt;inline-size&lt;/code&gt; lets you query a container's size only in, as the name might suggest, the inline dimension, and &lt;code&gt;normal&lt;/code&gt; doesn't let you query a container's size, only its style.&lt;/p&gt;

&lt;p&gt;I haven't mentioned this up until now, but you can also use the parent container's style in your conditions!&lt;/p&gt;

&lt;p&gt;Let's make a container, without any size available:&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;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;container-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;container-type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create our target element with some 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="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&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;And then make a rule for our container:&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;@container&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&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;This is called style query, if our container has at some point its background color set to &lt;code&gt;red&lt;/code&gt;, we can avoid our &lt;code&gt;h2&lt;/code&gt; blending in with the background.&lt;/p&gt;

&lt;p&gt;I should also mention that you can also nest containers inside of each other, like shown here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@container &amp;lt;condition&amp;gt; {
  @container &amp;lt;condition&amp;gt; {
    &amp;lt;style&amp;gt;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;According to caniuse.com &lt;code&gt;@container&lt;/code&gt; is currently supported by 93% of all browsers (as of December 2024).&lt;/p&gt;

&lt;p&gt;There is so much more to &lt;code&gt;@container&lt;/code&gt; rule than I can possibly cover here. If you're interested and want to find out more, check out these sites &lt;a href="https://w3c.github.io/csswg-drafts/css-contain-3/#container-rule" rel="noopener noreferrer"&gt;w3c&lt;/a&gt; &amp;amp; &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@container" rel="noopener noreferrer"&gt;mdn&lt;/a&gt;.&lt;/p&gt;

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