<?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: Ekaterina Vujasinović</title>
    <description>The latest articles on DEV Community by Ekaterina Vujasinović (@ekaterina_vu).</description>
    <link>https://dev.to/ekaterina_vu</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%2F319653%2F8a6443da-6568-4ea9-82b9-fe861d85eef6.jpg</url>
      <title>DEV Community: Ekaterina Vujasinović</title>
      <link>https://dev.to/ekaterina_vu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ekaterina_vu"/>
    <language>en</language>
    <item>
      <title>Quiz📣: How Well Do You Understand Asynchronous JavaScript?</title>
      <dc:creator>Ekaterina Vujasinović</dc:creator>
      <pubDate>Thu, 28 Oct 2021 13:37:47 +0000</pubDate>
      <link>https://dev.to/ditdot/quiz-how-well-do-you-understand-asynchronous-javascript-5e4j</link>
      <guid>https://dev.to/ditdot/quiz-how-well-do-you-understand-asynchronous-javascript-5e4j</guid>
      <description>&lt;p&gt;Over the last few weeks, we had a lot of discussions on asynchronous JavaScript and patterns we use in our projects to build performant apps. It resulted in an article - &lt;a href="https://www.ditdot.hr/en/4-tips-better-asynchronous-javascript-code"&gt;4 tips on writing better async/await code&lt;/a&gt;. Besides practical aspects like asynchronous coding patterns and best practices, one of the discussed topics was the importance of understanding how JavaScript handles asynchronous code under the hood.&lt;/p&gt;

&lt;p&gt;Asynchronous code is passed to wait in one of the queues and executed whenever the call stack is empty. Tasks in the queues and call stack are coordinated by the event loop - the key mechanism used by JavaScript to avoid blocking the main thread. Learn more about it &lt;a href="https://blog.bitsrc.io/understanding-asynchronous-javascript-the-event-loop-74cd408419ff"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We've collected 4 interesting examples of code (it looks like 4 is our favorite number 😉) that will help you test your knowledge of event loop and JavaScript asynchronous execution flow. Let's start ⏬&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Which Queue Is Executed First?
&lt;/h2&gt;

&lt;p&gt;Before diving deep into the event loop, call stack, and tasks, let's begin with a little warm-up question.&lt;/p&gt;

&lt;p&gt;Not all queues were created equal. Knowing that &lt;code&gt;setTimeout()&lt;/code&gt; callback is pushed to the task queue, and &lt;code&gt;then()&lt;/code&gt; callback to the microtask queue, which one do you think will log first?&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;// Task queue &lt;/span&gt;
&lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;timeout&lt;/span&gt;&lt;span class="dl"&gt;'&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;// Microtask queue &lt;/span&gt;
&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;promise&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;
  Show the answer 👇
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;promise&lt;/span&gt; 
&lt;span class="nx"&gt;timeout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The tasks scheduled in the task queue will run first. But wait, how come the output logged from the &lt;code&gt;setTimeout()&lt;/code&gt; callback appears second in our example?&lt;/p&gt;

&lt;p&gt;In each iteration, the event loop will run the oldest initially existing task in the task queue first, and all the microtasks in the microtask queue second. When the event loop starts its first iteration, the task queue contains only one task - the main program script run. The &lt;code&gt;setTimeout()&lt;/code&gt; callback is added to the task queue during the first iteration and will be queued from tasks only during the next iteration.&lt;/p&gt;

&lt;p&gt;To better understand these mind-blowing concepts, check this &lt;a href="https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/#why-this-happens"&gt;animated diagram&lt;/a&gt; by Jake Archibald.&lt;br&gt;
&lt;/p&gt;

&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  2. What Is the Output of the Code Below?
&lt;/h2&gt;

&lt;p&gt;To answer this question, you need to be familiar with the concepts like synchronous vs. asynchronous code order of execution and how the event loop is running tasks.&lt;/p&gt;

&lt;p&gt;Equally important, you also need to know which code runs synchronously and which asynchronously. Hint: not all Promise-related code is asynchronous. 🤯&lt;/p&gt;

&lt;p&gt;There are four &lt;code&gt;console.log()&lt;/code&gt; calls below.  What will be logged in the console and in which order?&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;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//A&lt;/span&gt;
    &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// B&lt;/span&gt;
    &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// C&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// D&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;
  Show the answer 👇
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* B */&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="cm"&gt;/* D */&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="cm"&gt;/* C */&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="cm"&gt;/* A */&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The code inside the &lt;code&gt;new Promise&lt;/code&gt; executor function runs synchronously before the Promise goes to a resolved state (when &lt;code&gt;resolve()&lt;/code&gt; is called). For this reason example code logs &lt;code&gt;1&lt;/code&gt; and sets variable &lt;code&gt;a&lt;/code&gt; value to &lt;code&gt;3&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The variable value remains unchanged in all further &lt;code&gt;console.log()&lt;/code&gt;calls.&lt;br&gt;
&lt;/p&gt;

&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  3. In What Order Will Letters Be Logged?
&lt;/h2&gt;

&lt;p&gt;How do DOM events fit in the event loop task handling mechanism?  What we have here is a &lt;code&gt;div&lt;/code&gt; container containing a &lt;code&gt;button&lt;/code&gt; element. Event listeners are added to both the button and the container. Since the click event will bubble up,  both listener handlers will be executed on a button click.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;What is the output after button click?&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;container&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="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;button&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="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;B&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="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;C&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;
  Show the answer 👇
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;B&lt;/span&gt;
&lt;span class="nx"&gt;A&lt;/span&gt;
&lt;span class="nx"&gt;C&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;No surprise here. The task of dispatching &lt;code&gt;click&lt;/code&gt; event and executing handler will be invoked via the event loop, with synchronous code logging first and &lt;code&gt;then()&lt;/code&gt; callback logging second. Next, the event bubbles up and the container event handler is executed.&lt;br&gt;
&lt;/p&gt;

&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Will the Output Change?
&lt;/h2&gt;

&lt;p&gt;The code is the same as in the previous example, with a small addition of &lt;code&gt;button.click()&lt;/code&gt; at the end. It is a weird UI design pattern where the button is clicked automatically. Do you think it's a game-changer or logging order stays the same? 🤔&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;container&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="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;button&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="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;B&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="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;C&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;
  Show the answer 👇
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;B&lt;/span&gt;
&lt;span class="nx"&gt;C&lt;/span&gt;
&lt;span class="nx"&gt;A&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The strings are indeed logged in different order. &lt;code&gt;button.click()&lt;/code&gt; is making all the difference, sitting at the bottom of the call stack and preventing microtask queue tasks from executing. Only after the call stack is emptied, &lt;code&gt;() =&amp;gt; console.log('A')&lt;/code&gt; will be queued from the microtasks.&lt;br&gt;
&lt;/p&gt;

&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Feel free to share your mind-boggling async &amp;amp; event loop related code examples in the comments ✍️. Don't forget to ❤️ and follow for more web dev content. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>quiz</category>
    </item>
    <item>
      <title>Dark Mode With One Line Of Code</title>
      <dc:creator>Ekaterina Vujasinović</dc:creator>
      <pubDate>Sat, 22 Aug 2020 13:24:20 +0000</pubDate>
      <link>https://dev.to/ekaterina_vu/dark-mode-with-one-line-of-code-4lkm</link>
      <guid>https://dev.to/ekaterina_vu/dark-mode-with-one-line-of-code-4lkm</guid>
      <description>&lt;p&gt;Dark mode can be implemented with a single line of code. Let’s see how it's done and the benefits and drawbacks of this simple approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  filter: invert(100%)
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;invert()&lt;/code&gt; function as the value of the &lt;code&gt;filter&lt;/code&gt; property will take the number from 0 to 1 or percentages from 0% to 100% to invert the colors of the element and its children. &lt;strong&gt;Applying &lt;code&gt;filter: invert(1)&lt;/code&gt; or &lt;code&gt;filter: invert(100%)&lt;/code&gt; results in fully inverted colors&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can use this single line of CSS to switch the color scheme from light to dark (or the other way around).&lt;/p&gt;

&lt;p&gt;To invert the colors of the entire website, you need to apply &lt;code&gt;filter: invert(100%)&lt;/code&gt; on the highest-level element of the DOM:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;invert&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Applying filter with toggle button
&lt;/h2&gt;

&lt;p&gt;To switch the theme, you need a toggle button and a class with dark mode styles to be toggled on the button click. Check the Codepen example below and click the button in the middle to change the color scheme:&lt;/p&gt;

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

&lt;p&gt;The &lt;code&gt;filter&lt;/code&gt; property inside the &lt;code&gt;.dark-mode&lt;/code&gt; class is responsible for changing the colors. &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 class will be toggled */&lt;/span&gt;
&lt;span class="nc"&gt;.dark-mode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;invert&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We must employ some basic JavaScript by targeting the &lt;code&gt;document.documentElement&lt;/code&gt; inside the listener function. Then we can toggle the &lt;code&gt;.dark-mode&lt;/code&gt; class on the top of the DOM hierarchy to apply the &lt;code&gt;filter: invert(100%)&lt;/code&gt; sitewide.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;button&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;.btn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="c1"&gt;// press the button to toggle the .dark-mode class&lt;/span&gt;&lt;br&gt;
&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark-mode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;})&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  The pros and cons of inverting all the pixels&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;The benefits of making your entire site switch from the light to the dark mode with &lt;code&gt;filter: invert(100%)&lt;/code&gt; are obvious: &lt;strong&gt;it's a quick and dirty solution&lt;/strong&gt;. And, like every quick solution, it also has some significant downfalls. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;filter&lt;/code&gt; applied on the top of the DOM tree is going to cascade down and affect all the child elements. It’s going to invert &lt;strong&gt;all the colors&lt;/strong&gt;. It results with the following list of problems (and let’s pretend that every bullet point ends with: “Additional code is necessary to fix this”):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Media like images and videos gets inverted, and it never looks good (but you probably still want to have the SVGs inverted). &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FkS_f8Mpp8-iXekVZTGmWHUAKezRUYuPptv13LoKoDefHJlVvSWr2Nf_DOcy_mzNvqY9Ci8f6J-FE6N4xRPF20OUox-v2z4_buYzlAUOTRxP9_cWpT8QRCSnV2Y8WIc247T-ysN20eA" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FkS_f8Mpp8-iXekVZTGmWHUAKezRUYuPptv13LoKoDefHJlVvSWr2Nf_DOcy_mzNvqY9Ci8f6J-FE6N4xRPF20OUox-v2z4_buYzlAUOTRxP9_cWpT8QRCSnV2Y8WIc247T-ysN20eA"&gt;&lt;/a&gt;&lt;/p&gt;
All pixels are inverted, including the image



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;All dark box-shadows will become highlights. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If your website has colors other than black, white, or grayish nuances, you might be surprised by how bad some colors look inverted. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FzawE5zEprOH-ZYQ7rFKNbPlmYXTCAG3KlIBqo203ifmnLIwmfjmEZ967cA8QvBMOgjNxv3o7eIjB8sLoaC-JrJW6YazXBtdjtbfTGzpHkYrw1bAUPEN5ByaP0DiWzgrW51YUOZKDCA" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FzawE5zEprOH-ZYQ7rFKNbPlmYXTCAG3KlIBqo203ifmnLIwmfjmEZ967cA8QvBMOgjNxv3o7eIjB8sLoaC-JrJW6YazXBtdjtbfTGzpHkYrw1bAUPEN5ByaP0DiWzgrW51YUOZKDCA"&gt;&lt;/a&gt;&lt;/p&gt;
Light blue color becomes not-so-pretty brown color 





&lt;ul&gt;
&lt;li&gt;Where there was once a sufficient contrast on the light background, things can change when color gets inverted and when it's against the dark background.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FZqhUt3hzkswoniTD2QzzrTqOi_uQMVQAXfTdw8nmv3K1moY1vlDqlK9KQQUxwdJaCmnf4hck7Tz1s6h50hUPeWlmHPq9NXccB2klLFRlh9LPjsbOH9kVxv5yJ8crgplMkxsZ8L9mBg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FZqhUt3hzkswoniTD2QzzrTqOi_uQMVQAXfTdw8nmv3K1moY1vlDqlK9KQQUxwdJaCmnf4hck7Tz1s6h50hUPeWlmHPq9NXccB2klLFRlh9LPjsbOH9kVxv5yJ8crgplMkxsZ8L9mBg"&gt;&lt;/a&gt;&lt;/p&gt;
The contrast of the inverted color on the dark background is very low





&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Think about &lt;code&gt;hover&lt;/code&gt;, &lt;code&gt;focus&lt;/code&gt;, &lt;code&gt;active&lt;/code&gt;, &lt;code&gt;visited&lt;/code&gt;, and all other special element states. Do colors convey the state of the elements when inverted or is the color meaning lost? What about interactives?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some advanced UI advice by Steve Schoger that adds to the point&lt;br&gt;
&lt;a href="https://twitter.com/steveschoger/status/1151160261170126850" rel="noopener noreferrer"&gt;https://twitter.com/steveschoger/status/1151160261170126850&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This list could go on and on, dealing with all kinds of usability and accessibility details that would be sorely missed when inverting the entire color scheme. The point is - you expected to implement the dark mode with a single line of code and spent the entire day writing CSS to fix all the problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  To invert or not to invert?
&lt;/h2&gt;

&lt;p&gt;The final verdict for &lt;code&gt;filter: invert(100%)&lt;/code&gt; is: it is super-useful for making the details look good. You could use it to switch the colors of the entire site though if your site is very simple and monochromatic.&lt;/p&gt;

&lt;p&gt;In all other cases, you should probably try some content-aware techniques instead. For example, here is the &lt;a href="https://www.ditdot.hr/en/dark-mode-website-tutorial" rel="noopener noreferrer"&gt;Dark Mode - The prefers-color-scheme Website Tutorial article &lt;/a&gt;(and its &lt;a href="https://github.com/ditdot-dev/dark-mode-example" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;) I wrote on implementing the dark mode with &lt;code&gt;prefers-color-scheme&lt;/code&gt; media-query, variables, and JavaScript. &lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>CSS Comparison Functions clamp(), max() and min()</title>
      <dc:creator>Ekaterina Vujasinović</dc:creator>
      <pubDate>Tue, 19 May 2020 12:34:08 +0000</pubDate>
      <link>https://dev.to/ekaterina_vu/css-comparison-functions-clamp-max-and-min-4aon</link>
      <guid>https://dev.to/ekaterina_vu/css-comparison-functions-clamp-max-and-min-4aon</guid>
      <description>&lt;p&gt;We use relative length units to build responsive/fluid layouts. Besides being flexible, elements whose size depends on the size of another element or the viewport, also have a bad habit of sometimes &lt;strong&gt;growing or shrinking more than we would like them to&lt;/strong&gt;. For example, if we define the font size with &lt;code&gt;vw&lt;/code&gt; unit alone, text can easily become illegible if viewport size gets too small. &lt;/p&gt;

&lt;p&gt;Breaking a bad habit is tough - and in this case it may require some serious thinking and calculations. We usually solve these problems with media queries or different &lt;code&gt;calc()&lt;/code&gt; techniques to achieve more fluid effect. It's especially true when it comes to the elements that don't have &lt;code&gt;width&lt;/code&gt; property (and consequently &lt;code&gt;max-width&lt;/code&gt; and &lt;code&gt;min-width&lt;/code&gt;), like the above-mentioned font size. &lt;/p&gt;

&lt;p&gt;Comparison functions can help us build responsive designs with less time and fewer lines of code. Functions &lt;code&gt;clamp()&lt;/code&gt;, &lt;code&gt;min()&lt;/code&gt; and &lt;code&gt;max()&lt;/code&gt; (specified in &lt;a href="https://drafts.csswg.org/css-values-4/#comp-func"&gt;CSS Values and Units Module Level 4&lt;/a&gt;) set upper and/or lower value limits, compute and compare values of the arguments passed to the function, and apply the calculated value to the property. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;clamp()&lt;/code&gt;, &lt;code&gt;min()&lt;/code&gt; and &lt;code&gt;max()&lt;/code&gt; can take values or math expressions as arguments (or basically anything that resolves to a value). They can be used, let me quote &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/clamp"&gt;MDN&lt;/a&gt; here: anywhere a &lt;code&gt;&amp;lt;length&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;frequency&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;angle&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;time&amp;gt;&lt;/code&gt;,&lt;code&gt;&amp;lt;percentage&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;number&amp;gt;&lt;/code&gt;, or &lt;code&gt;&amp;lt;integer&amp;gt;&lt;/code&gt; is allowed. That’s a lot of possible use cases to consider, and in this post I explored the most obvious ones.&lt;/p&gt;

&lt;h1&gt;
  
  
  clamp()
&lt;/h1&gt;

&lt;p&gt;Function &lt;code&gt;clamp()&lt;/code&gt; takes three parameters: a minimum value, a central, preferred value, and a maximum value. The resolved value will always remain between the minimum and maximum.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;clamp()&lt;/code&gt; calculates property value based on the central value. &lt;strong&gt;If the calculated value falls between the minimum and maximum, the central value will be applied to the element. If the calculated value falls below minimum or exceeds maximum, minimum or maximum will be applied respectively&lt;/strong&gt;. There is no need for &lt;code&gt;calc()&lt;/code&gt; function when passing math expressions in the comparison function. &lt;/p&gt;

&lt;p&gt;The syntax is simple and logical:&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;/* css */&lt;/span&gt;
&lt;span class="nc"&gt;.element&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;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;50vw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;600px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="c"&gt;/* width: clamp(min, preferred, max); */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on the viewport size, the upper CSS ruleset will apply the following widths to the element: &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Viewport&lt;/th&gt;
&lt;th&gt;Applied width clamp()&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;200px - 1200px&lt;/td&gt;
&lt;td&gt;50vw&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt; 200px&lt;/td&gt;
&lt;td&gt;100px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;gt; 1200px&lt;/td&gt;
&lt;td&gt;600px&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Try it for yourself in the &lt;code&gt;clamp()&lt;/code&gt; &lt;a href="https://codepen.io/Ekaterina_Vu/pen/QWjxJvm"&gt;demo&lt;/a&gt; below: &lt;br&gt;
&lt;iframe height="600" src="https://codepen.io/Ekaterina_Vu/embed/QWjxJvm?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;

&lt;p&gt;Check another &lt;a href="https://codepen.io/Ekaterina_Vu/pen/PoPBwwR"&gt;demo&lt;/a&gt; to see how both the paragraph text and the heading are being smoothly resized between the value limits. No jumps as with media queries. The ratio between the font size of the headline and body text grows as the viewport gets bigger but nothing will ever get too big or too small. &lt;/p&gt;

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

&lt;p&gt;This is a simple example and is far from perfect - vertical rhythm, modular scale, line length, and bazillion other typography related things - it all could be implemented better. But if I ever decide to improve it, I will probably use comparison functions for much of the above.&lt;/p&gt;

&lt;h1&gt;
  
  
  max() and min()
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Function &lt;code&gt;max()&lt;/code&gt; calculates and applies the largest value from the provided range of values. Likewise, function &lt;code&gt;min()&lt;/code&gt; calculates and applies the smallest value from the range.&lt;/strong&gt; They can take one or more parameters.&lt;/p&gt;

&lt;p&gt;Check the Codepen &lt;a href="https://codepen.io/Ekaterina_Vu/pen/jObKRRP"&gt;demo&lt;/a&gt; below to see both functions in action: &lt;/p&gt;

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

&lt;p&gt;Yes, both &lt;code&gt;min()&lt;/code&gt; and &lt;code&gt;max()&lt;/code&gt; can be replaced with &lt;code&gt;max-width&lt;/code&gt; or &lt;code&gt;min-width&lt;/code&gt; if the element has width property and only two parameters are passed into the function. It sounds a bit counterintuitive, but &lt;code&gt;max()&lt;/code&gt; actually sets the lower size limit and &lt;code&gt;min()&lt;/code&gt; the upper size limit.&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;/* css */&lt;/span&gt;

&lt;span class="c"&gt;/* min() */&lt;/span&gt;
&lt;span class="nc"&gt;.element&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;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50vw&lt;/span&gt;&lt;span class="p"&gt;,&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="c"&gt;/* gives the same result as: */&lt;/span&gt;
&lt;span class="nc"&gt;.element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&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="c"&gt;/* max() */&lt;/span&gt;
&lt;span class="nc"&gt;.element&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;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50vw&lt;/span&gt;&lt;span class="p"&gt;,&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="c"&gt;/* gives the same result as: */&lt;/span&gt;
&lt;span class="nc"&gt;.element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50vw&lt;/span&gt;&lt;span class="p"&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;500px&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;The upper CSS code applies following width values to the element, depending on the viewport size:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Viewport&lt;/th&gt;
&lt;th&gt;Applied width max()&lt;/th&gt;
&lt;th&gt;Applied width min()&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&amp;gt; 1000px&lt;/td&gt;
&lt;td&gt;50vw&lt;/td&gt;
&lt;td&gt;500px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt; 1000px&lt;/td&gt;
&lt;td&gt;500px&lt;/td&gt;
&lt;td&gt;50vw&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;You can pass multiple parameters into both &lt;code&gt;max()&lt;/code&gt; and &lt;code&gt;min()&lt;/code&gt;&lt;/strong&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="c"&gt;/* css */&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;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3em&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4vw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="c"&gt;/* the smallest value will be applied */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;max()&lt;/code&gt; and &lt;code&gt;min()&lt;/code&gt; with multiple parameters are potentially capable of doing some serious responsive stuff with a single line of code. However, I find them a bit incomprehensive - it's hard to set the right arguments and it's even harder to check which value gets applied 🤯. Maybe there are some best practices I'm not aware of. &lt;/p&gt;

&lt;p&gt;In the following &lt;a href="https://codepen.io/Ekaterina_Vu/pen/qBOJLaW"&gt;demo&lt;/a&gt; the rectangle changes its width and color as the width property takes three different values: &lt;br&gt;
&lt;iframe height="600" src="https://codepen.io/Ekaterina_Vu/embed/qBOJLaW?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comparison functions can be nested within other comparison functions&lt;/strong&gt;. For example, function &lt;code&gt;clamp()&lt;/code&gt; can be alternatively written as &lt;code&gt;max(minimum, min(preferred, maximum))&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Comparison functions are new to me and I still haven't find time to fully explore them. They have only recently entered some major browsers but already have &lt;a href="https://caniuse.com/#feat=css-math-functions"&gt;decent&lt;/a&gt; browser support. &lt;/p&gt;

&lt;p&gt;I can imagine comparison functions being used in web typography. It's not like it will absolve us from using media queries or &lt;code&gt;calc()&lt;/code&gt;, but in many cases they can make our job a lot easier.&lt;/p&gt;

&lt;p&gt;Potential use cases of comparison functions probably stretch far beyond responsive width and font-size. I was thinking about how to use them with colors (still thinking 🥴). Maybe you have some interesting ideas? Share your thoughts in comments.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How can object-fit property save you from misusing the background images</title>
      <dc:creator>Ekaterina Vujasinović</dc:creator>
      <pubDate>Mon, 17 Feb 2020 11:44:40 +0000</pubDate>
      <link>https://dev.to/ekaterina_vu/how-can-object-fit-property-save-you-from-misusing-the-background-images-hk0</link>
      <guid>https://dev.to/ekaterina_vu/how-can-object-fit-property-save-you-from-misusing-the-background-images-hk0</guid>
      <description>&lt;p&gt;It's a very common situation - you have an image that needs to fit its content box without losing the aspect ratio. It seems that the easiest way to solve the problem is to insert your picture via CSS &lt;code&gt;background-image&lt;/code&gt; and give it the &lt;code&gt;background-size: cover&lt;/code&gt; property. There are also other &lt;code&gt;background-*&lt;/code&gt; properties that can help you with positioning and styling. &lt;/p&gt;

&lt;p&gt;However, inserting images with CSS is not always the most appropriate choice. &lt;strong&gt;It's how the purely decorative images should be handled&lt;/strong&gt;. When it comes to the images that are providing any kind of meaningful information, 👉 &lt;strong&gt;&lt;code&gt;object-fit&lt;/code&gt; gives us the ability to manipulate the content inside the &amp;lt;img&amp;gt; tag in a very similar way as &lt;code&gt;background-size&lt;/code&gt; does with CSS-inserted background images&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: Don't use &lt;code&gt;background-*&lt;/code&gt; for images, videos or other replaced elements that are providing any kind of information, concepts or functionality. 👉 &lt;strong&gt;Use inline images and style them in CSS with &lt;code&gt;object-fit&lt;/code&gt; and &lt;code&gt;object-position&lt;/code&gt; instead&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For the sake of brevity, I will write mostly about handling images, instead referring to each kind of replaced elements separately. The main idea is the same, though. &lt;/p&gt;

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

&lt;p&gt;👉 &lt;em&gt;background-&lt;/em&gt;* vs &lt;em&gt;object-fit&lt;/em&gt;&lt;br&gt;
👉 Background images are not accessible&lt;br&gt;
👉 Background images are not SEO-friendly&lt;br&gt;
👉 Are there any performance issues with background images?&lt;br&gt;
👉 Conclusion&lt;/p&gt;
&lt;h2&gt;
  
  
  Background vs object-fit &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;object-fit&lt;/code&gt; is used to fit image or video (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Replaced_element"&gt;and every other replaced element&lt;/a&gt;) to its content box. Images with &lt;strong&gt;non-decorative content&lt;/strong&gt; should be inserted like this into the HTML document and further styled in the CSS stylesheet 👇&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;!--index.html--&amp;gt;&lt;/span&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;'meaningful-image.jpg'&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;'this text describes the image'&lt;/span&gt; 
 &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;'.my-html-image'&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="c"&gt;/*style.css*/&lt;/span&gt;
&lt;span class="nc"&gt;.my-html-image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;object-fit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;object-position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;left&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;top&lt;/span&gt; &lt;span class="m"&gt;15%&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;Check the CodePen demo below for working example of &lt;code&gt;object-fit&lt;/code&gt; values:&lt;br&gt;
&lt;iframe height="600" src="https://codepen.io/Ekaterina_Vu/embed/poJjXqR?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decorative background images&lt;/strong&gt; should be inserted like this into the CSS stylesheet 👇&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;/*style.css*/&lt;/span&gt;
&lt;span class="nc"&gt;.my-div&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(my-special-image-url.jpg)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background-repeat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&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="nb"&gt;left&lt;/span&gt; &lt;span class="m"&gt;10%&lt;/span&gt; &lt;span class="nb"&gt;top&lt;/span&gt; &lt;span class="m"&gt;15%&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="n"&gt;cover&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;As you can see, it's not the amount or the complexity of code that makes a difference between those two ways of inserting images. The thing is that using &lt;code&gt;background-*&lt;/code&gt; for non-decorative content &lt;strong&gt;have some serious drawbacks&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background images are not accessible &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Background images are meant to be purely decorative and it would be incorrect to make them "audible". It can be tempting to simply build a pie chart with conic gradient in CSS, but by doing it you are probably excluding people who cannot see the chart.&lt;/p&gt;

&lt;p&gt;Screen readers and other assistive technologies rely on structural markup, and therefore, it is your responsibility as the developer to ensure that your HTML is semantically correct  in describing the functional purpose of the content. Background images don't have a corresponding markup element - you set them in CSS directly - so, &lt;strong&gt;they are 'invisible' to the screen readers&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Besides proper HTML structure, there are other important accessibility features, like &lt;em&gt;alt&lt;/em&gt; attributes for images, that cannot be used with &lt;code&gt;background-*&lt;/code&gt; properties. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Browsers do not provide any special information on background images to assistive technology. This is important primarily for screen readers, as a screen reader will not announce its presence and therefore convey nothing to its users. 👉 If the image contains information critical to understanding the page's overall purpose, it is better to describe it semantically in the document.&lt;/p&gt;
-MDN, &lt;cite&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/background"&gt;https://developer.mozilla.org/en-US/docs/Web/CSS/background&lt;/a&gt;&lt;/cite&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Background images are not SEO-friendly &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Google parses the HTML of your pages to index images, &lt;strong&gt;but doesn't index CSS images&lt;/strong&gt;. 👉 If you want your images to rank in Google Image search then you best use &amp;lt;img&amp;gt; tag with the &lt;em&gt;src&lt;/em&gt; attribute pointing at the image. That said, it would be a shame to hide your visual content behind the &lt;code&gt; background-image&lt;/code&gt;, especcially if it's a custom content that is additionally backing up your message. &lt;/p&gt;

&lt;p&gt;As previously mentioned, &lt;code&gt;background&lt;/code&gt; is purely CSS property and doesn't have a corresponding HTML tag or attributes. 👉 For good SEO results images should be placed near relevant text, have alt tags and maybe a caption - you can't do any of those with &lt;code&gt;background-*&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Are there any performance issues with background images? &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Yes, but there is hope on the horizon. There are some significant shortcomings regarding performance of background images:  &lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Background images are discovered by browser only after all CSS in page's &amp;lt;head&amp;gt; element has been downloaded and parsed&lt;/strong&gt;. If there is a substantial amount of CSS, it may cause slower loading of the background image.&lt;/p&gt;

&lt;p&gt;👉 Likewise, it is impossible to &lt;strong&gt;provide high-res images&lt;/strong&gt; without writing a bunch of device pixel ratio media queries, which is a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/-webkit-device-pixel-ratio"&gt;non-standard feature&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;image-set()&lt;/strong&gt; is a new feature that allows us to use different background images for different screen densities (just like &lt;em&gt;srcset&lt;/em&gt; attribute in &amp;lt;img&amp;gt; tag) - hence solving the second problem. Even more so, image-set() can be used with the new &lt;em&gt;preload&lt;/em&gt; feature 👇&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The preload value of the &amp;lt;link&amp;gt; element's rel attribute lets you declare fetch requests in the HTML's &amp;lt;head&amp;gt;, specifying resources that your page will need very soon, which you want to start loading early in the page lifecycle, before browsers' main rendering machinery kicks in. 👉 This ensures they are available earlier and are less likely to block the page's render, improving performance.&lt;/p&gt;
- MDN, &lt;cite&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content"&gt;https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content&lt;/a&gt;&lt;/cite&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, hopefully, if the browser support ever gets just a bit better for both &lt;a href="https://caniuse.com/#search=image-set()"&gt;image-set()&lt;/a&gt; and &lt;a href="https://caniuse.com/#search=preload"&gt;preload&lt;/a&gt;, we can consider both issues solved. &lt;/p&gt;

&lt;p&gt;For more information, read this &lt;a href="https://web.dev/preload-responsive-images/#preloading-background-images-using-image-set"&gt;article on Google Developers&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Background images are not "bad" per se, they just have some shortcomings when implemented in the incorrect way. You should definitely choose them for abstract background pattern, background color / gradient, or some blurry, decorative image. But for your hero image or any other meaningful content, you might consider the &amp;lt;img&amp;gt; and &amp;lt;picture&amp;gt; tags, together with &lt;code&gt;object-fit&lt;/code&gt; and &lt;code&gt;object-position&lt;/code&gt;. The latter provides much more opportunities for accessible, easily discoverable and performant images.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Lesser-known CSS display values</title>
      <dc:creator>Ekaterina Vujasinović</dc:creator>
      <pubDate>Mon, 10 Feb 2020 12:29:02 +0000</pubDate>
      <link>https://dev.to/ekaterina_vu/lesser-known-css-display-values-448j</link>
      <guid>https://dev.to/ekaterina_vu/lesser-known-css-display-values-448j</guid>
      <description>&lt;p&gt;If you are just like me and have spent a last couple of years coding without being aware of how many CSS display values are out there, this could be a useful post for you. I will leave out the values that are most widely used (&lt;code&gt;block&lt;/code&gt;, &lt;code&gt;inline&lt;/code&gt;, &lt;code&gt;inline-block&lt;/code&gt;, &lt;code&gt;flex&lt;/code&gt;, &lt;code&gt;grid&lt;/code&gt;, &lt;code&gt;table&lt;/code&gt; with all the internal display values and &lt;code&gt;none&lt;/code&gt;) since there are already so many great articles about them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;p&gt;👉 What display is all about&lt;br&gt;
👉 display: inline-flex and display: inline-grid&lt;br&gt;
👉 display: flow-root&lt;br&gt;
👉 display: list-item&lt;br&gt;
👉 display: contents&lt;br&gt;
👉 display: ruby&lt;/p&gt;
&lt;h2&gt;
  
  
  What display is all about &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;According to the &lt;a href="https://drafts.csswg.org/css-display/#the-display-properties"&gt;CSS Display Module Level 3 spec&lt;/a&gt; 👇&lt;/p&gt;

&lt;blockquote&gt;
The display property defines an element’s display type, which consists of the &lt;b&gt;two basic qualities&lt;/b&gt; of how an element generates boxes:&lt;br&gt;&lt;br&gt;

👉 &lt;b&gt;the inner display type&lt;/b&gt;, which defines the kind of formatting context it generates, dictating how its descendant boxes are laid out.&lt;br&gt;&lt;br&gt;

👉 &lt;b&gt;the outer display type&lt;/b&gt;, which dictates how the principal box itself participates in flow layout.
&lt;/blockquote&gt;

&lt;p&gt;In other words, the inner display type describes the &lt;strong&gt;behaviour of element's children&lt;/strong&gt;, while the outer display type defines whether the element is &lt;strong&gt;block-level or inline-level&lt;/strong&gt;, that is, how it interacts with other, outer elements. &lt;/p&gt;

&lt;p&gt;Right now, display property single-value syntax feels kind of incomplete and doesn't always let you specify both inner and outer display type explicitly. Sometimes it's hard to figure out right away how the element behaves.&lt;/p&gt;

&lt;p&gt;Luckily, the CSS Display Module Level 3 also defines new, two-value syntax for setting display values, with outer and inner display type values set separately (e.g. &lt;code&gt;block flex&lt;/code&gt; instead of just &lt;code&gt;flex&lt;/code&gt;). This feature has already been implemented in Firefox, but other browsers don't support it yet. &lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;em&gt;display: inline-flex&lt;/em&gt; and &lt;em&gt;display: inline-grid&lt;/em&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Both flex and grid containers are behaving like &lt;strong&gt;block items by default&lt;/strong&gt;, as both &lt;code&gt;flex&lt;/code&gt; and &lt;code&gt;grid&lt;/code&gt; display values are setting the outer display type to block. This means that each container will occupy the full width available, even if its corresponding HTML element is an inline item (like &amp;lt;span&amp;gt;). &lt;/p&gt;

&lt;p&gt;In case we need to modify the &lt;strong&gt;outer behaviour&lt;/strong&gt; of the grid / flex containers, e.g. to position them side-by-side in the same row,  👉&lt;code&gt;inline-flex&lt;/code&gt; and  &lt;code&gt;inline-grid&lt;/code&gt; display values will make them behave like inline elements, without affecting the layout of items inside the containers.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  &lt;em&gt;display: flow-root&lt;/em&gt;&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;flow-root&lt;/code&gt; is an &lt;strong&gt;inner display type value&lt;/strong&gt;, which means that it sets the inner flow of the elements. In order to properly understand &lt;code&gt;flow-root&lt;/code&gt;, we need to dig into something called &lt;strong&gt;Block Formatting Context (BFC)&lt;/strong&gt;. There is a definition in the &lt;a href="https://www.w3.org/TR/CSS2/visuren.html#normal-flow"&gt;spec&lt;/a&gt;, but it's easier to explain with an example. &lt;/p&gt;

&lt;p&gt;There are two red &amp;lt;div&amp;gt; elements in CodePen below, with identical children elements and formatted in the same way, except for the display value. The first container has default, &lt;code&gt;block&lt;/code&gt; display value, while the second one is an &lt;code&gt;inline-block&lt;/code&gt; element. Do you see &lt;strong&gt;collapsed margins&lt;/strong&gt; in the first container? 😱&lt;/p&gt;

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

&lt;p&gt;Top margin of the blue square and bottom margin of the paragraph are somehow ending up outside of the parent element. In the second container, we avoided margins collapsing, since it occurs only between blocks belonging to the same Block Formatting Context and 👉 display value of &lt;code&gt;inline-block&lt;/code&gt; creates a brand &lt;strong&gt;new BFC&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;inline-block&lt;/code&gt; is &lt;a href="https://developer.mozilla.org/enUS/docs/Web/Guide/CSS/Block_formatting_context"&gt;not the only property creating a new BFC&lt;/a&gt;, though. What if we want to keep the margins from collapsing, but also keep our container block element, remaining in his own row in layout? Among other hacks, we could do it by setting overflow to hidden, but apparently, this method may have &lt;a href="https://www.smashingmagazine.com/2017/12/understanding-css-layout-block-formatting-context/"&gt;unwanted side effects&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;flow-root&lt;/code&gt; display value is a solution to our problem as it always &lt;strong&gt;generates a block container box and establishes a new BFC&lt;/strong&gt; for its content. As an inner display type, it is actually short for &lt;code&gt;block flow-root&lt;/code&gt;, whereas &lt;code&gt;inline flow-root&lt;/code&gt; is identical to &lt;code&gt;inline-block&lt;/code&gt; value. &lt;/p&gt;

&lt;p&gt;Now we can use display values to &lt;strong&gt;create new BFC on both block and inline elements&lt;/strong&gt;, which can be useful not only when handling margins, but for example, when we need to contain floats without using the clearfix hack.&lt;/p&gt;

&lt;p&gt;Rememeber, the two-value syntax is not quite alive yet, so you can't use &lt;code&gt;display: inline flow-root&lt;/code&gt; (except in Firefox). 👉 Use &lt;code&gt;display: flow-root&lt;/code&gt; (but check the &lt;a href="https://caniuse.com/#feat=flow-root"&gt;browser support first&lt;/a&gt;) and &lt;code&gt;display:inline-block&lt;/code&gt; instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;display: list-item&lt;/em&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;list-item&lt;/code&gt; is the &lt;strong&gt;default display value for &amp;lt;li&amp;gt; element&lt;/strong&gt;. It generates a block box for the content and a separate inline box for the marker. In Firefox, the &amp;lt;summary&amp;gt; element also has &lt;code&gt;list-item&lt;/code&gt; default display value, but only if it is the first child of the &amp;lt;details&amp;gt; element. &lt;/p&gt;

&lt;p&gt;You can specify image, position and type for the list marker, but not distinct styles (like colors or fonts). However, in Firefox &lt;code&gt;list-item&lt;/code&gt; creates a &lt;code&gt;::marker&lt;/code&gt; pseudoelement, which has a wider set of allowable properties.&lt;/p&gt;

&lt;p&gt;Yes, I use this one quite a lot, but most of the time I wasn't aware that list items use this special display value. Why does it even matter? Well, in the two-value syntax &lt;code&gt;list-item&lt;/code&gt; can be combined with both outer and inner display types, making really long display values (like &lt;code&gt;inline flow-root list-item&lt;/code&gt;).😄&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;display: contents&lt;/em&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Display values of &lt;code&gt;contents&lt;/code&gt; and &lt;code&gt;none&lt;/code&gt; define &lt;strong&gt;whether an element generates display boxes at all&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;While element with &lt;code&gt;display:none&lt;/code&gt; will be removed from the layout together with its descendants, 👉 display value of &lt;code&gt;contents&lt;/code&gt; &lt;strong&gt;removes only the element from the document tree and its children are replacing it&lt;/strong&gt;. Use it with care as it is marked as an experimental feature on MDN 🧪, although with &lt;a href="https://caniuse.com/#feat=css-display-contents"&gt;fairly good browser support&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It makes it especially beneficial to use &lt;strong&gt;with Grid or Flexbox&lt;/strong&gt;, since only the direct descendants of grid or flex containers are behaving as flex /grid items. In case we need to go down one level and make 'the grandchildren' behave as flex / grid items of the main container, 👉 &lt;code&gt;display:content&lt;/code&gt; on the direct child of the main container will prevent it from generating a box, and its children will take its place.&lt;/p&gt;

&lt;p&gt;In the example below, both purple rectangles are grid containers with orange rectangles as children and grid items. Yellow rectangles are children of the first orange rectangle. In the second container,👉 first orange rectangle is given display value of &lt;code&gt;contents&lt;/code&gt; and is no longer visible. His children (yellow rectangles) are taking his place as grid-items, acting as if they were direct descendants of purple rectangle.😎&lt;/p&gt;

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

&lt;h2&gt;
  
  
  &lt;em&gt;display: ruby&lt;/em&gt; &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Ruby annotations are used for adding explanation or pronunciation to base text (usually to East Asian characters). There are two ways of adding a ruby annotation:&lt;/p&gt;

&lt;p&gt;👉 with HTML &amp;lt;ruby&amp;gt; element (and corresponding &amp;lt;rt&amp;gt;, &amp;lt;rb&amp;gt;, &amp;lt;rtc&amp;gt; and &amp;lt;rbc&amp;gt; elements for the internal structure)&lt;br&gt;
 👉 with CSS display value of &lt;code&gt;ruby&lt;/code&gt; (and corresponding &lt;code&gt;ruby-text&lt;/code&gt;, &lt;code&gt;ruby-base&lt;/code&gt;,&lt;code&gt;ruby-text-container&lt;/code&gt; and &lt;code&gt;ruby-base-container&lt;/code&gt; display values for the internal structure)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use CSS &lt;code&gt;display: ruby&lt;/code&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For document languages (such as XML) that **do not have pre-defined ruby elements **like HTML does, corresponding elements can be translated to ruby elements with the CSS &lt;code&gt;display: ruby&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use HTML &amp;lt;ruby&amp;gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In all other cases. If you have &amp;lt;ruby&amp;gt; element available, you should use it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Authors using a language (such as HTML) that supports dedicated ruby markup 👉 should use that markup rather than styling arbitrary elements (like &amp;lt;span&amp;gt;) with ruby display values. Using the correct markup ensures that screen readers and non-CSS renderers can interpret the ruby structures.&lt;/p&gt;
—W3C, &lt;cite&gt;&lt;a href="https://drafts.csswg.org/css-ruby-1/#intro"&gt;CSS Ruby Layout Module Level 1&lt;/a&gt;&lt;/cite&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is, &lt;strong&gt;the two aren’t mutually exclusive&lt;/strong&gt;, but I probably won't use CSS &lt;code&gt;display: ruby&lt;/code&gt; very often. I tried them both in Firefox and found some subtle differences in default behaviour, which indicates there is still room to further investigate this matter.🤯 &lt;/p&gt;

&lt;p&gt;It seems like HTML &amp;lt;ruby&amp;gt; alone is good enough for a simple ruby structure, along with some optional ruby-related CSS properties to fine tune the positioning of the ruby text.&lt;/p&gt;

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