<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Tobias Ahlin</title>
		<description>Home of tobiasahlin.com</description>
		<link>https://tobiasahlin.com</link>
		<atom:link href="https://tobiasahlin.com/feed.xml" rel="self" type="application/rss+xml" />
		
			<item>
				<title>Responsive type scales with composable CSS utilities</title>
				<description>&lt;div class=&quot;blog-banner&quot;&gt;
  &lt;div class=&quot;blog-banner-content&quot;&gt;
    &lt;img src=&quot;/static/fluid-type-icon.svg&quot; width=&quot;153&quot; height=&quot;155&quot; /&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;!--more--&gt;

&lt;style&gt;
:root {
  --min-size: 16;
  --max-size: 16;
  --viewport-min: 320;
  --viewport-max: 2400;

  --container-min: 320;
  --container-max: 2400;
}

.h1, .h2, .h3, .h4 {
  --font-size: calc(var(--min-size) * 1px + (var(--max-size) - var(--min-size)) * (100vw - var(--viewport-min) * 1px) / (var(--viewport-max) - var(--viewport-min)));
  --font-size-container: calc(var(--min-size) * 1px + (var(--max-size) - var(--min-size)) * (100cqw - var(--container-min) * 1px) / (var(--container-max) - var(--container-min)));
  font-size: clamp(var(--min-size) * 1px, var(--font-size-container), var(--max-size) * 1px);
  line-height: 1.1em;
  text-wrap: balance;
}

.h1 {
  --min-size: 32;
  --max-size: 128;
}

.h2 {
  --min-size: 24;
  --max-size: 96;
}

.h3 {
  --min-size: 16;
  --max-size: 64;
}

.h4 {
  --min-size: 12;
  --max-size: 48;
}

.f4min {
  --min-size: var(--h4);
}

.fmin-s {
  --viewport-min: var(--breakpoint-s);
}

.fmax-xl {
  --viewport-max: var(--breakpoint-xl);
}

.post-demo-content {
  text-align: left;
  padding-top: 60px;
  padding-bottom: 120px;
}

.subheader {
  letter-spacing: 0.1em;
  font-weight: 500;
  font-size: 12px;
  margin-top: 40px;
}

&lt;/style&gt;

&lt;p&gt;If you’ve ever attempted to create responsive type that seamlessly adapts and scales between pre-determined sizes within a type scale based on viewport or container widths, you may have wrestled with JavaScript or wrangled with CSS calculators. But with the help of &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/calc&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;calc()&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/clamp&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clamp()&lt;/code&gt;&lt;/a&gt;, and a somewhat wonky use of &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties&quot;&gt;CSS vars&lt;/a&gt;, we can simplify this process and tap into the dynamism that modern CSS affords. We can create truly fluid type scales, with composable and responsive type utilities that let your type resize and adapt to the viewport or container width.&lt;/p&gt;

&lt;p&gt;Here’s a demo of what we’ll set up (resize the browser window to preview the effect—it works in the latest version of all major browsers):&lt;/p&gt;

&lt;div class=&quot;post-demo-content&quot;&gt;
  &lt;div class=&quot;subheader&quot;&gt;32px - 124px&lt;/div&gt;
  &lt;div class=&quot;h1&quot;&gt;Whereas recognition of the inherent&amp;nbsp;dignity&lt;/div&gt;
  &lt;div class=&quot;subheader&quot;&gt;24px - 80px&lt;/div&gt;
  &lt;div class=&quot;h2&quot;&gt;Whereas recognition of the inherent&amp;nbsp;dignity&lt;/div&gt;
  &lt;div class=&quot;subheader&quot;&gt;16px - 64px&lt;/div&gt;
  &lt;div class=&quot;h3&quot;&gt;Whereas recognition of the inherent&amp;nbsp;dignity&lt;/div&gt;
  &lt;div class=&quot;subheader&quot;&gt;12px - 48px&lt;/div&gt;
  &lt;div class=&quot;h4&quot;&gt;Whereas recognition of the inherent&amp;nbsp;dignity&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;What follows is an in-depth exploration of how to achieve this effect. If you simply whish to drop this functionality into a project, I’ve collected a range of type scale CSS utilities—with breakpoint classes and other methods of achieveing higher granularity of type control—in a small type scale library called &lt;a href=&quot;https://github.com/tobiasahlin/bendable&quot;&gt;bendable&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;jumping-through-hoops&quot;&gt;Jumping through hoops&lt;/h2&gt;

&lt;p&gt;Creating this calculation should, in theory, be reasonably straightforward, but the rigidity of CSS &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;calc()&lt;/code&gt; can make the process feel like you’re navigating a semantic minefield. Unfortunately, CSS &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;calc()&lt;/code&gt; does currently not allow for implicit conversions between unitless numbers and pixel values, so getting the syntax exactly right can be tricky. These restrictions &lt;a href=&quot;https://www.w3.org/TR/css-values-4/#calc-type-checking&quot;&gt;have been relaxed in the css-values-4 spec&lt;/a&gt;, but until those changes are implemented and widely supported in browsers, we’ll have to work around the current limitations.&lt;/p&gt;

&lt;p&gt;One method of bypassing the current limitations is to, whenever possible, pass around values as unitless numbers, not as pixel values, and then convert them to pixels when we need them as pixels (by multiplying them with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1px&lt;/code&gt;). With this strategy, we can achieve adaptive type that stays true to a pre-determined type scale. Here’s a breakdown of the calculation (line breaks and comments for clarity):&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container-adaptive&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;--font-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;/* Minimum size in pixels -&amp;gt; the starting point */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;+&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;/* Diff between min and max -&amp;gt; how much should we add in total? */&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt;
      &lt;span class=&quot;c&quot;&gt;/* Container size minus starting point -&amp;gt; how far are we? */&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cqw&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--container-min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;/* Diff between min and max container width -&amp;gt; the range */&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--container-max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--container-min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;/* Clamp between min and max, to avoid overshooting */&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--font-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;unpacking-the-calculation&quot;&gt;Unpacking the calculation&lt;/h2&gt;

&lt;p&gt;In plain English, the formula to calculate the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;font-size&lt;/code&gt; is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minimum font size&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;diff between min and max font size&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;current container width relative to its min and max values&lt;/code&gt;. In its enterity, it reads &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;calc(var(--min-size) * 1px + (var(--max-size) - var(--min-size)) * (100cqw - var(--container-min) * 1px) / (var(--container-max) - var(--container-min)))&lt;/code&gt;. Again, the calculation is a bit tricky to get right with CSS &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;calc()&lt;/code&gt;, and looks a bit wonky, because we:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Can’t add a unitless number to a pixel value (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;calc(5px + 5)&lt;/code&gt; is invalid)&lt;/li&gt;
  &lt;li&gt;Can’t divide a pixel value by a pixel value (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;calc(10px / 2px)&lt;/code&gt; is invalid)&lt;/li&gt;
  &lt;li&gt;Can’t multiply a pixel value with a pixel value (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;calc(5px * 2px)&lt;/code&gt; is invalid)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, when performing addition and subtraction, both values need to be of the same format. When conducting division and multiplication, at least one of the arguments must be a unitless number. To ensure the calculation works within these constraints, we initially set all values as unitless numbers and convert them to pixels when needed.&lt;/p&gt;

&lt;p&gt;When it all comes together, our variable and calculation setup can then look like something like this (notice the variables’ lack of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;px&lt;/code&gt; units—pixels are implied in all of these variables):&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;--container-min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;320&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;--container-max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;--viewport-min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;320&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;--viewport-max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.container-adaptive&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;--font-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cqw&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--container-min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--container-max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--container-min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)));&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--font-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.viewport-adaptive&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;--font-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;100vw&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--viewport-min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--viewport-max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--viewport-min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)));&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--font-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally, we use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clamp()&lt;/code&gt; to avoid overshooting our min and max values. With this specific setup, the font size will be set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;12px&lt;/code&gt; when the container or viewport is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;320px&lt;/code&gt; or smaller, scale linearly from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;12px&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;18px&lt;/code&gt; between a container/viewport size of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;320px&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2400px&lt;/code&gt;, and then stop at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;18px&lt;/code&gt; when the container or viewport width reaches &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2400px&lt;/code&gt;. To set the size relative to the viewport size, we use the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vw&lt;/code&gt;&lt;/a&gt; unit, and to set it relative to the container, we use the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_container_queries&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cqw&lt;/code&gt;&lt;/a&gt; unit.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-utilities&quot;&gt;Setting up utilities&lt;/h2&gt;

&lt;p&gt;With that as our starting point, we can set up a few utilities to independently set the maximum and minimum values, to easily scale between two points in a type scale:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;--container-min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;320&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;--container-max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;/* Setup size calculation for all max utilities */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h1-max&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.h2-max&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.h3-max&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.h4-max&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.h5-max&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.h6-max&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.h7-max&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.h8-max&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;--font-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cqw&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--container-min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--container-max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--container-min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)));&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--font-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.h1-max&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h2-max&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;96&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h3-max&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h4-max&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h5-max&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h6-max&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h7-max&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h8-max&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--max-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.h1-min&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h2-min&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;96&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h3-min&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h4-min&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h5-min&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h6-min&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h7-min&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.h8-min&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;--min-size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With those utilities, this markup effectively reproduces the demo in the beginning of the post:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Mix and match as you wish --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;h1&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;h5-min h1-max&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;h2&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;h6-min h2-max&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;h3&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;h7-min h3-max&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;h4&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;h8-min h4-max&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;…but you can use any combination of max and min utilities to easily change the start and end sizes, and it’ll all smoothly scale between those two sizes.&lt;/p&gt;

&lt;p&gt;The versatility of fluid and adaptive typography presents a range of exciting possibilities. I’ve explored this concept further in a small type scale library called &lt;a href=&quot;https://github.com/tobiasahlin/bendable&quot;&gt;bendable&lt;/a&gt;, which captures these techniques in the form of a responsive type scale, with some extra sugar on top.&lt;/p&gt;

&lt;h2 id=&quot;limitations&quot;&gt;Limitations&lt;/h2&gt;

&lt;p&gt;An important and significant limitation of this technique, because of the existing CSS &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;calc()&lt;/code&gt; restrictions, is that you currently can’t use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rem&lt;/code&gt;s to set your type. This limitation will be resolved as browsers add support for &lt;a href=&quot;https://www.w3.org/TR/css-values-4/#calc-type-checking&quot;&gt;the relaxed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;calc()&lt;/code&gt; restrictions&lt;/a&gt;, but until then, this technique is limited to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;px&lt;/code&gt; units.&lt;/p&gt;
</description>
				<pubDate>Fri, 22 Sep 2023 01:12:00 +0000</pubDate>
				<link>https://tobiasahlin.com/blog/responsive-fluid-css-type-scales/</link>
				<guid isPermaLink="true">https://tobiasahlin.com/blog/responsive-fluid-css-type-scales/</guid>
			</item>
		
			<item>
				<title>Hiding empty elements with CSS :empty and :has()</title>
				<description>&lt;div class=&quot;blog-banner&quot;&gt;
  &lt;div class=&quot;blog-banner-content&quot;&gt;
    &lt;img src=&quot;/static/empty-icon.png&quot; width=&quot;153&quot; height=&quot;155&quot; /&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;!--more--&gt;

&lt;style&gt;
  .item {
    border-radius: 3px;
    background-color: #A2CBFA;
    border: 1px solid #4390E1;
    box-sizing: border-box;
    padding: 10px;
    font-size: 14px;
    font-weight: 600;
    color: #fff;
    flex-grow: 1;
    flex-basis: 50%;
    text-align: center;
    margin: 0 20px 20px;
    box-shadow: 0 2px 2px rgba(0,90,250,0.05),
      0 4px 4px rgba(0,90,250,0.05),
      0 8px 8px rgba(0,90,250,0.05),
      0 16px 16px rgba(0,90,250,0.05);
  }

  .item-results {
    padding: 5px 8px;
    border-radius: inherit;
    background-color: rgba(255, 255, 255, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.6);
    margin-top: 10px;
  }

  .item-result {
    border: 1px solid #086bd4;
    background-color: #4390E1;
    padding: 2px 0;
    margin: 5px 0 2px;
    border-radius: inherit;
  }

  .post-content-wrapper {
    display: flex;
  }

  .item1:empty,
  .item2:has(.item-results:empty),
  .item3:not(.item3:has(.item-result)) {
    box-shadow: none;
    background-color: transparent;
    border-style: dashed;
    border-width: 2px;
  }

  .item2 .item-results:empty {
    display: none;
  }
&lt;/style&gt;

&lt;p&gt;You might be used to adding and removing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.open&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.closed&lt;/code&gt; classes on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;div&lt;/code&gt;s and containers to control their state styles. What if we could just write CSS that reflected the state of the DOM, without having to additionally handle state by toggling classes? In this post, we’ll explore how to hide elements with the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/:empty&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:empty&lt;/code&gt;&lt;/a&gt; pseudo-class if they have no children, and how to make the pattern more granular and practical when we combine it with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/:has&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:has()&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/:not&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:not()&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;hiding-an-empty-element&quot;&gt;Hiding an empty element&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:empty&lt;/code&gt; matches any element that has no children. The pseudo-class is &lt;a href=&quot;https://caniuse.com/?search=%3Aempty&quot;&gt;supported by all major browsers&lt;/a&gt;, and is safe to use even if you’re targeting Internet Explorer. We can use it in combination with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;display&lt;/code&gt; property to hide an element if it’s empty:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:empty&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;none&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this example, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:empty&lt;/code&gt; pseudo-class is used to select elements with the class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.container&lt;/code&gt; that have no children (including text nodes), and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;display: none&lt;/code&gt; rule is used to hide them.&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- This will be visible --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Some text&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- This will be hidden --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;item item1&quot;&gt;Some text&lt;/div&gt;
  &lt;div class=&quot;item item1&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id=&quot;hiding-an-element-that-has-an-empty-child&quot;&gt;Hiding an element that has an empty child&lt;/h2&gt;

&lt;p&gt;Assume that we have a some HTML markup that looks something like this, that we dynamically populate with suggestions inside of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.results&lt;/code&gt;…&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;h4&amp;gt;&lt;/span&gt;Suggestions&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;results&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    ...
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;…and we want to hide the entire &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.container&lt;/code&gt; when the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.results&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;div&lt;/code&gt; is empty (since the container itself will never be empty). For scenarios like this, we can combine the the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:empty&lt;/code&gt; pseudo-class with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:has()&lt;/code&gt;, to hide any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.container&lt;/code&gt; that has an empty &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.results&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;div&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:has&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;.results&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:empty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;none&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- This will be visible --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;h4&amp;gt;&lt;/span&gt;Suggestions&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;results&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Result 1&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Result 2&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- This will be hidden --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;h4&amp;gt;&lt;/span&gt;Suggestions&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;results&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;item item2&quot;&gt;
    Suggestions
    &lt;div class=&quot;item-results&quot;&gt;
      &lt;div class=&quot;item-result&quot;&gt;Result 1&lt;/div&gt;
      &lt;div class=&quot;item-result&quot;&gt;Result 2&lt;/div&gt;
      &lt;div class=&quot;item-result&quot;&gt;...&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;item item2&quot;&gt;
    &lt;div class=&quot;item-results&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Here, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.container&lt;/code&gt; selects all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.container&lt;/code&gt;s, and then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:has()&lt;/code&gt; filters them to only those that have an empty &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.results&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;div&lt;/code&gt;. Note that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.has()&lt;/code&gt; is only supported by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;84.68%&lt;/code&gt; of all major browsers, and you may want to &lt;a href=&quot;https://www.npmjs.com/package/css-has-pseudo&quot;&gt;use a polyfill&lt;/a&gt; while awaiting broader support.&lt;/p&gt;

&lt;h2 id=&quot;hiding-a-parent-element-that-doesnt-contain-a-certain-child&quot;&gt;Hiding a parent element that doesn’t contain a certain child&lt;/h2&gt;

&lt;p&gt;You can equally choose to hide a container based on if it doesn’t contain a certain child, say a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.result&lt;/code&gt;. Imagine that our markup looks something like this, where we return a series of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.result&lt;/code&gt; divs:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;h4&amp;gt;&lt;/span&gt;Suggestions&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;result&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;result&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;result&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For a scenario like this, we can combine the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:not()&lt;/code&gt; pseudo-class with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:has()&lt;/code&gt; to hide the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.container&lt;/code&gt; if it doesn’t contain any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.result&lt;/code&gt; elements:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:not&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:has&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;.result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;none&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- This will be visible --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;h4&amp;gt;&lt;/span&gt;Suggestions&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;result&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Result 1&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;result&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Result 2&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;result&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- This will be hidden --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;h4&amp;gt;&lt;/span&gt;Suggestions&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;item item3&quot;&gt;
    Suggestions
    &lt;div class=&quot;item-result&quot; style=&quot;margin-top: 10px&quot;&gt;Result 1&lt;/div&gt;
    &lt;div class=&quot;item-result&quot;&gt;Result 2&lt;/div&gt;
    &lt;div class=&quot;item-result&quot;&gt;...&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;item item3&quot;&gt;
    &lt;div&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Here, we start by selecting all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.container&lt;/code&gt; elements, then we exclude elements from that list with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:not()&lt;/code&gt;, and we exclude all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.container&lt;/code&gt; elements that contain a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.result&lt;/code&gt;. What remains is any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.container&lt;/code&gt; that doens’t include a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.result&lt;/code&gt;, and we use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;display: none&lt;/code&gt; to hide it. Note that unlike &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:has()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:not()&lt;/code&gt; is actually &lt;a href=&quot;https://caniuse.com/?search=%3Anot()&quot;&gt;supported by all major browsers&lt;/a&gt;, and can safely be used without a polyfill.&lt;/p&gt;

&lt;p&gt;We might not be able to avoid toggling classes completely to handle states, but with the help of these patterns we can to a larger extent let our styles be a function of the content that’s being displayed, and build more robust experiences.&lt;/p&gt;
</description>
				<pubDate>Wed, 15 Mar 2023 01:05:00 +0000</pubDate>
				<link>https://tobiasahlin.com/blog/hiding-an-element-if-its-empty/</link>
				<guid isPermaLink="true">https://tobiasahlin.com/blog/hiding-an-element-if-its-empty/</guid>
			</item>
		
			<item>
				<title>Selecting previous siblings with CSS :has()</title>
				<description>&lt;div class=&quot;blog-banner&quot;&gt;
  &lt;div class=&quot;blog-banner-content&quot;&gt;
    &lt;img src=&quot;/static/previous-sibling/icon.png&quot; width=&quot;175&quot; height=&quot;125&quot; /&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;!--more--&gt;

&lt;style&gt;
  .item {
    border-radius: 3px;
    background-color: #A2CBFA;
    border: 1px solid #4390E1;
    box-sizing: border-box;
    width: 20px;
    height: 20px;
    margin: 0 20px 20px;
    box-shadow: 0 2px 2px rgba(0,90,250,0.05),
      0 4px 4px rgba(0,90,250,0.05),
      0 8px 8px rgba(0,90,250,0.05),
      0 16px 16px rgba(0,90,250,0.05);
  }

  .circle {
    border-radius: 20px;
    width: 40px;
    height: 40px;
  }

  .item:has(+ .circle1) {
    width: 40px;
    height: 40px;
  }

  .item:has(+ * + .circle2) {
    width: 40px;
    height: 40px;
  }

  .item:has(+ * + * + .circle21) {
    width: 40px;
    height: 40px;
  }

  .item:has(~ .circle3) {
    width: 40px;
    height: 40px;
  }

  .item:has(~ * + .circle4) {
    width: 40px;
    height: 40px;
  }

  .post-content-wrapper {
    display: flex;
    align-items: center;
    justify-content: center;
  }
&lt;/style&gt;

&lt;p&gt;One of the more maddening limitations of CSS was for long its inability to select elements based on their children or preceding siblings. This made it impossible to construct CSS selectors that could target previous siblings of an element, but the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/:has&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;has:()&lt;/code&gt;&lt;/a&gt; pseudo-class (along with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:not()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:where()&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:is()&lt;/code&gt; from &lt;a href=&quot;https://w3c.github.io/csswg-drafts/selectors/#relational&quot;&gt;Selectors Level 4&lt;/a&gt;) has thrown out the old limitations and opened up a new world of possibilities when working with selectors.&lt;/p&gt;

&lt;p&gt;As of this writing, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:has()&lt;/code&gt; is supported by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;84.68%&lt;/code&gt; of all major browsers (including Chrome and Safari), with Firefox being the notable exception. Experimental support for Firefox launched in July 2022 and can be enabled through the flag &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;layout.css.has-selector.enabled&lt;/code&gt;—you can track the progress &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=418039&quot;&gt;through this Bugzilla issue&lt;/a&gt;. Until that ships, you can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:has()&lt;/code&gt; pseudo-class if you’re not targeting or supporting Firefox, or if you &lt;a href=&quot;https://www.npmjs.com/package/css-has-pseudo&quot;&gt;use a polyfill&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;selecting-the-previous-sibling&quot;&gt;Selecting the previous sibling&lt;/h2&gt;

&lt;p&gt;Imagine that we have a series of elements, like this:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;box&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;box&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;box&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;circle&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;box&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item circle circle0&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;…and we want to select and style the element that comes &lt;em&gt;before&lt;/em&gt; the circle. The &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_combinator&quot;&gt;adjacent sibling combinator&lt;/a&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+&lt;/code&gt;) can select an element that immediately follows another element, and we can combine it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:has()&lt;/code&gt; that to select only the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.box&lt;/code&gt; that’s immediately followed by a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.circle&lt;/code&gt; (or from the circle’s perspective, its previous sibling):&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:has&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(+&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.circle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item circle circle1&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;You can think of this selector as first 1) selecting all boxes, and then 2) filtering the elements to only those that match the pattern “box + circle”, which will only return the circle’s previous sibling.&lt;/p&gt;

&lt;h2 id=&quot;selecting-the-nth-previous-sibling&quot;&gt;Selecting the nth previous sibling&lt;/h2&gt;

&lt;p&gt;It’s possible to use the adjacent sibling combinator to select any specific element that preceds another. We can select the 2nd previous sibling by using two adjacent sibling combinators:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:has&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.circle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item circle circle2&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;If you want to, you can equally scope the selector to a class (rather than the catch-all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*&lt;/code&gt;). In this instance &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.box&lt;/code&gt; siblings:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:has&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(+&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.box&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.circle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This selector can be difficult to grok and parse. It might help to think of it as selecting all boxes (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.box&lt;/code&gt;), and then filtering those elements so that the remaining &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.box&lt;/code&gt; is the one that matches the pattern “self + box + circle”, which will only be the 2nd previous sibling.&lt;/p&gt;

&lt;p&gt;If you want to select the 3rd previous sibling, you can use three adjacent sibling combinators…&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:has&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.circle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item circle circle21&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;…and so on and so forth. You can keep on adding adjacent sibling combinators (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+&lt;/code&gt;) for as long as you want, to select any nth preceding element.&lt;/p&gt;

&lt;h2 id=&quot;selecting-all-preceding-siblings&quot;&gt;Selecting all preceding siblings&lt;/h2&gt;

&lt;p&gt;If you want to select &lt;em&gt;all&lt;/em&gt; previous siblings, you can combine the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:has()&lt;/code&gt; pseudo-class with the general sibling combinator (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~&lt;/code&gt;), which matches  the second element as long as it follows the first, regardless of its position:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:has&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(~&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.circle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item circle circle3&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In other words, as long as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.box&lt;/code&gt; in this example is followed by a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.circle&lt;/code&gt; at some point, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.box&lt;/code&gt; will be selected and styled.&lt;/p&gt;

&lt;h2 id=&quot;selecting-all-preceding-siblings-except-the-most-adjacent-sibling&quot;&gt;Selecting all preceding siblings except the most adjacent sibling&lt;/h2&gt;

&lt;p&gt;Finally, we can combine the general sibling combinator (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~&lt;/code&gt;) with the adjacent sibling combinator (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+&lt;/code&gt;) and select all preceding elements except the most adjacent one:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:has&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(~&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.circle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item circle circle4&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This selector selects any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.box&lt;/code&gt; that matches the pattern “self followed by at any point a box + circle”.&lt;/p&gt;
</description>
				<pubDate>Thu, 09 Mar 2023 12:05:00 +0000</pubDate>
				<link>https://tobiasahlin.com/blog/previous-sibling-css-has/</link>
				<guid isPermaLink="true">https://tobiasahlin.com/blog/previous-sibling-css-has/</guid>
			</item>
		
			<item>
				<title>A brief introduction to A/B-testing</title>
				<description>&lt;div class=&quot;blog-banner&quot;&gt;
  &lt;div class=&quot;blog-banner-content&quot;&gt;
    &lt;img src=&quot;/static/ab-testing/icon.svg&quot; width=&quot;145px&quot; /&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;!--more--&gt;

&lt;p&gt;A/B-testing is a guiding compass for making product decisions. More technically, it’s a method for quantifying the impact of product variations. The process can’t tell us if one variation is unequivocally “better” than another, but it &lt;em&gt;can&lt;/em&gt; tell us which of a set of variations is better at producing a certain effect, encouraging a behavior, or achieving a goal.&lt;/p&gt;

&lt;p&gt;The basic method is similar to a clinical trial with a placebo group. By testing two or more variations of an experience (labeled A, B, C, etc.) and measuring how they cause similar groups of people to behave differently on average, we can assess a design’s impact. What we need at the minimum, then, is one control (A), one variant (B), and a random sample of users. The two versions could be our product in its current state, and a new idea that we want to compare it against:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/ab-testing/test-variants.png&quot; alt=&quot;A/B test variants&quot; width=&quot;2091&quot; height=&quot;1090&quot; style=&quot;padding: 0 3%; box-sizing: border-box;&quot; loading=&quot;lazy&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At a surface level, A/B testing is as simple as that: build two variations of something and measure the difference in behavior.&lt;/p&gt;

&lt;h2 id=&quot;incrementalism-and-learning&quot;&gt;Incrementalism and learning&lt;/h2&gt;

&lt;p&gt;Before we go into the details of running such a test, let’s take a step back and examine the underlying thought process. A philosophy that’s usually coupled with A/B-testing is incrementalism: the idea that we can build great products, make innovative leaps, and overcome daring obstacles by implementing gradual and measurable improvements. A vision can guide this iteration and experimentation, but rather than acting as a blueprint that gets fully built and realized in one humongous project—a risky and expensive endeavor—that vision typically serves as a north star. Small incremental improvements build up and inch us ever closer towards it, but experiments feedback into the vision and slowly transform it over time, placing the north star forever out of reach.&lt;/p&gt;

&lt;p&gt;To embrace this philosophy and effectively accumulate insights and improvements through experimentation, we need to foster a culture and process that supports learning. If we don’t, we risk going in circles—running tests that have no impact, and that teach us nothing new. An important goal for a data-driven design organization is not just making an impact but learning as quickly as possible about a moving target. We need to allocate our resources based on how promising our different strategies seem at any given point. What’s worth focusing on will vary over time as your product and audience grows and transforms, and it’s something that you will have to learn and relearn continuously.&lt;/p&gt;

&lt;p&gt;With learning as a core pillar of this philosophy, we can map experiment-driven design as a circular process of &lt;strong&gt;building&lt;/strong&gt;, &lt;strong&gt;measuring&lt;/strong&gt;, and &lt;strong&gt;learning&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/ab-testing/process.png&quot; alt=&quot;A/B test process&quot; width=&quot;1315&quot; height=&quot;1232&quot; style=&quot;padding: 0 16%; box-sizing: border-box;&quot; loading=&quot;lazy&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Every test doesn’t necessarily have to make your product better—but every test should teach you something. The A/B-testing process usually includes the articulation of hypotheses to facilitate that learning: we make sure that we capture our beliefs before running tests so that we can compare them with our new beliefs that we’ve acquired after seeing the results.&lt;/p&gt;

&lt;p&gt;At a more granular level, an A/B-testing process can look something like this:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Ideate&lt;/strong&gt;: Come up with one or more ideas that you want to test, based on your previous data, experience, problems, and goals.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Hypothesize&lt;/strong&gt;: Define hypotheses for each idea, outline why you think those ideas could have an impact, and what result you expect to see.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Plan&lt;/strong&gt;: To gaurd against your own biases and what you &lt;em&gt;want&lt;/em&gt; to believe, you can tie different outcomes to follow-up actions before running the test. Define an array of outcomes, and tie those outcomes to different follow-up actions.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Create&lt;/strong&gt;: Design and implement the variations you believe in most.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Expose&lt;/strong&gt;: Ship the variations to a subset of your users in a randomized trial.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Wait&lt;/strong&gt;: Wait for the tests to get enough exposure to offer meaningful insights.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Analyze&lt;/strong&gt;: Analyze the data from the test.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Deliberate&lt;/strong&gt;: Discuss what the results mean and how they validate or disprove your hypotheses.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Ship&lt;/strong&gt;, &lt;strong&gt;iterate&lt;/strong&gt;, or &lt;strong&gt;abandon&lt;/strong&gt;: Based on your learnings, roll out a variation to all users, iterate on a direction before running another test, or abandon ideas in favor of exploring other directions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;running-a-test&quot;&gt;Running a test&lt;/h2&gt;

&lt;p&gt;Say that we have a website that looks like illustration &lt;strong&gt;A&lt;/strong&gt; (control) below: we have a logo in the top left, a menu in the top right, an image of our product, a header, and a short description. We then have two large buttons visible above the fold: “Sign up” and “Login.”&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/ab-testing/test-variants.png&quot; alt=&quot;A/B test variants&quot; width=&quot;2091&quot; height=&quot;1090&quot; style=&quot;padding: 0 3%; box-sizing: border-box;&quot; loading=&quot;lazy&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Someone in our organization has proposed that we should move the “Login” button to the menu in the top right, and keep the “Sign up” button as is (&lt;strong&gt;B&lt;/strong&gt;). They hypothesize that making the “Sign up” button the most prominent call to action will cause more people to see it, which will lead more people to sign up.&lt;/p&gt;

&lt;p&gt;To measure the impact of that change, we need to implement design B and expose a random subset of our users to it, alongside the default experience, which will act as a control. The exact proportion of our visitors (here 20%) that you enroll in a test will vary depending on the test and circumstances. The more users that get enrolled in an experiment the faster you’ll get the data that you need to analyze it, but make sure to not expose more users than necessary. After all, a variation might mistakenly make your product worse, and you want to mitigate any potential negative effects. In our hypothetical scenario, half of the visitors assigned to the test will see variation A, and half of them will see variation B.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/ab-testing/test-distribution.png&quot; alt=&quot;A/B test distribution&quot; width=&quot;1486&quot; height=&quot;835&quot; style=&quot;padding: 0 10%; box-sizing: border-box;&quot; loading=&quot;lazy&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The experiences are identical in every single aspect except the moved “Login” button. If we see that people using the B-version of our website are more likely to sign up, we can conclude that the altered button &lt;strong&gt;causes&lt;/strong&gt; that effect.&lt;/p&gt;

&lt;p&gt;In other words, we can establish a causational relationship between design B and a behavioral change: an increase in sign-ups. Not just a correlation—this is why we need a control group to compare against. If we implement &lt;strong&gt;B&lt;/strong&gt;, launch it to all our users, and then notice an increase in sign-ups, that increase would only correlate with the launch of the new design—it could as well be caused by a random tweet, a holiday, or a mention in a podcast. We wouldn’t know for sure, so we wouldn’t be able to draw any conclusions about the effects of the new design.&lt;/p&gt;

&lt;p&gt;We also need the users to be randomly assigned to each cell to infer a causal relationship. If we select users for the cells by different criteria and end up with more engaged users in one of the groups, it might make that cell perform better regardless of the introduced change: the skewed selection of users is already more engaged on average. If we randomize the distribution of users, we can expect that all attributes (engagement, age, experience, etc.) are equally distributed between the groups, and won’t influence the outcome.&lt;/p&gt;

&lt;h2 id=&quot;you-become-what-you-measure&quot;&gt;You become what you measure&lt;/h2&gt;

&lt;p&gt;Presume that we run this test, and after analyzing it, we see a statistically significant four percentage-point increase in sign-ups for variation &lt;em&gt;B&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/ab-testing/test-variants-lift.png&quot; alt=&quot;A/B test success&quot; width=&quot;2136&quot; height=&quot;1219&quot; style=&quot;padding: 0 3%; box-sizing: border-box;&quot; loading=&quot;lazy&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Variation B looks like a clear winner! Should we launch it? Here’s where we need to return to the notion that an A/B-test can’t tell us if &lt;strong&gt;B&lt;/strong&gt; is unequivocally better than &lt;strong&gt;A&lt;/strong&gt;. If our team’s goal is to increase sign-ups and we only measure sign-ups to assess if our tests are successful or not, we’ll likely run precisely these kinds of tests, where we promote the one feature connected to our goal while neglecting or diminishing other features. In this instance, the result can be a slow but steady accumulation of changes that taken together go against common sense: we’ll make it increasingly difficult for already signed up users to access the product.&lt;/p&gt;

&lt;p&gt;If the only thing we measure is the metric that’s fundamental for our success, we have a destructive setup that will enforce skewed incentives to promote features connected to our goal while neglecting other parts of the experience. If other teams in the same organization have similarly skewed incentives, it’s a recipe for conflicts and counterproductive back-and-forths.&lt;/p&gt;

&lt;p&gt;Unless we keep track of other key metrics and keep an eye out for accidental changes in different behaviors, we risk accumulating a myriad of unwanted side effects. When running the test outlined in this example, we might need to measure successful logins and retention (returning users over a certain period) in addition to sign-ups to understand if the change is introducing friction for already signed up users.&lt;/p&gt;

&lt;p&gt;In other words, the goals you set up and the key metrics that you keep track of will undoubtedly influence your product decisions. They form the restrictions that you iterate within.&lt;/p&gt;

&lt;h2 id=&quot;balancing-impact-vs-learnings&quot;&gt;Balancing impact vs. learnings&lt;/h2&gt;

&lt;p&gt;Why are we spending so much time on analyzing the effects of such a tiny difference? Wouldn’t it be more worthwhile to test more drastic changes? We could, without a doubt, introduce more ambitious and more significant changes. The challenge is that the more we change in one single test, the more difficult it can be to understand the results of that test—to pull it apart and learn precisely what variable caused which behavioral change.&lt;/p&gt;

&lt;p&gt;On the flip side, if we don’t change enough, we might fail to produce any meaningful changes at all, or at least not impactful enough to be noticeable. If we focus on learning and incremental improvements, then, there’s a U-shaped relationship between how much we change in a test, and how much we can typically learn from it:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/ab-testing/learnings-vs-impact.png&quot; alt=&quot;A/B-test learning vs amount of change&quot; width=&quot;1508&quot; height=&quot;1103&quot; style=&quot;padding: 0 12% 0 3%; box-sizing: border-box;&quot; loading=&quot;lazy&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If we don’t change enough, the impact will be too small to be noticeable. The difference will be unobservable or negligible. If we change too much—e.g., completely redesign the entire product—the introduced changes and the produced outcomes can become a tangled mess. We’ve no idea what variable that caused what effect. Clear and valuable insights are somewhere in the middle. Developing a sense of how significant changes to test is part of learning how to utilize A/B-tests effectively. It’s different from product to product and depends on how well-optimized your product already is.&lt;/p&gt;

&lt;p&gt;Importantly, this doesn’t mean that you &lt;em&gt;shouldn’t&lt;/em&gt; test more significant and visionary changes or ideas—it just means that every test is a gamble, and the bigger the change, the higher the risk of blurring learnings. At the same time, an ambitious change &lt;em&gt;might&lt;/em&gt; hit the jackpot and make a substantial and meaningful impact.&lt;/p&gt;

&lt;h2 id=&quot;a-defense-against-regressions&quot;&gt;A defense against regressions&lt;/h2&gt;

&lt;p&gt;This process might seem to be a terribly expensive way of improving a product, and to be fair, it is. We’re spending a lot of time conducting tests that we could’ve spent building and shipping new features. So, why is it worth it? Or rather, when? As a rule of thumb, the more users you have, the more damage you can cause by shipping features that, despite your best intentions, happen to make the product worse for your average user.&lt;/p&gt;

&lt;p&gt;The A/B-testing process really shines when it’s more expensive to make mistakes than to control for them. As your user base grows and your product matures, A/B-testing and data-driven design become an increasingly valuable tool not only to learn and iterate but to defend yourself against regressions. We can use it to gate the innovation process and only launch changes that we know make the product better—we introduce an objective selection process that only lets the fittest ideas survive. An overly zealous application of that selection process might shut out any change which’s effects aren’t quantifiable (which isn’t great—everything that matters isn’t quantifiable), but done right it can democratize the creative process and create an experimentation platform with clear goals and restrictions that we can iterate within.&lt;/p&gt;
</description>
				<pubDate>Wed, 20 May 2020 07:50:00 +0000</pubDate>
				<link>https://tobiasahlin.com/blog/introduction-to-ab-testing/</link>
				<guid isPermaLink="true">https://tobiasahlin.com/blog/introduction-to-ab-testing/</guid>
			</item>
		
			<item>
				<title>Chaining styles with a JavaScript Proxy</title>
				<description>&lt;div class=&quot;blog-banner&quot;&gt;
  &lt;div class=&quot;blog-banner-content&quot;&gt;
    &lt;div class=&quot;post-chain-wrapper&quot;&gt;
      &lt;svg class=&quot;post-chain-svg&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 82.7 82.7&quot;&gt;&lt;path fill=&quot;#FFF&quot; d=&quot;M71.6 64.2l-7.5 7.4c-.9.9-2.1 1.3-3.4 1.3-1.4 0-2.5-.5-3.4-1.4L46.8 61.1c-.9-.9-1.4-2.1-1.4-3.4 0-1.4.6-2.7 1.7-3.7.1.1.4.4.9 1l1.1 1.1c.2.2.5.4 1 .8.4.3.9.5 1.3.7.4.1.9.2 1.4.2 1.4 0 2.5-.5 3.4-1.4.9-.9 1.4-2.1 1.4-3.4 0-.5-.1-1-.2-1.4-.1-.4-.3-.9-.7-1.3-.3-.4-.6-.8-.8-1-.2-.2-.5-.6-1.1-1.1-.5-.5-.9-.8-1-.9 1-1.1 2.2-1.6 3.6-1.6s2.5.5 3.4 1.4l10.5 10.5c.9.9 1.4 2.1 1.4 3.4.3 1.1-.2 2.3-1.1 3.2zM35.7 28.8c-.1-.1-.4-.4-.9-1l-1.1-1.1c-.2-.2-.5-.4-1-.8-.4-.3-.9-.5-1.3-.7-.4-.1-.9-.2-1.4-.2-1.4 0-2.5.5-3.4 1.4-.9.9-1.4 2.1-1.4 3.4 0 .5.1 1 .2 1.4.1.4.3.9.7 1.3.3.4.6.8.8 1 .2.2.5.6 1.1 1.1.5.5.9.8 1 .9-1 1-2.2 1.6-3.6 1.6s-2.5-.5-3.4-1.4L11.2 25.3c-.9-.9-1.4-2.1-1.4-3.4 0-1.3.5-2.4 1.4-3.4l7.5-7.4c1-.9 2.1-1.4 3.4-1.4 1.4 0 2.5.5 3.4 1.4l10.4 10.5c.9.9 1.4 2.1 1.4 3.4.1 1.5-.5 2.7-1.6 3.8zm42.8 21.7L67.9 39.9c-2.8-2.8-6.3-4.3-10.3-4.3-4.1 0-7.6 1.5-10.5 4.5l-4.5-4.5c3-2.9 4.5-6.4 4.5-10.6 0-4.1-1.4-7.5-4.2-10.3L32.4 4.3C29.6 1.4 26.1 0 22.1 0 18 0 14.6 1.4 11.8 4.2l-7.5 7.4C1.4 14.4 0 17.8 0 21.9s1.4 7.5 4.3 10.3l10.5 10.5c2.8 2.8 6.3 4.3 10.3 4.3 4.1 0 7.6-1.5 10.5-4.5l4.5 4.5c-3 2.9-4.5 6.4-4.5 10.6 0 4.1 1.4 7.5 4.2 10.3l10.4 10.5c2.8 2.9 6.3 4.3 10.3 4.3 4.1 0 7.5-1.4 10.3-4.2l7.5-7.4c2.9-2.8 4.3-6.2 4.3-10.3.1-4-1.3-7.5-4.1-10.3z&quot; /&gt;&lt;/svg&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
  .post-chain-wrapper {
    border-radius: 50%;
    padding: 25px;
    background-color: #000;
    height: 44px;
    width: 44px;
    margin: 0 auto;
  }
  .post-chain-svg { max-height: 100%; }
&lt;/style&gt;

&lt;!--more--&gt;

&lt;p&gt;One of the delights of working with Ruby and jQuery is the ability to chain methods, enabling you to conveniently invoke multiple methods on the same target. In jQuery, for example, most methods return a jQuery object, so you can build a chain of methods where every new method operates on the previous target. This enables you to update some styles, run an animation, and update an attribute, all without querying for that element over and over again:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.menu&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#fff&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;light&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fadeIn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Short and sweet. If you’ve updated the styles of an object with vanilla JavaScript, you might’ve been annoyed about the fact that you can’t chain style changes, and so you have to do something like this:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;menu&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.menu&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;menu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#fff&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;menu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;backgroundColor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#000&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;menu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;opacity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are a few different ways of making this more convenient, but the other day I started thinking about if it would be possible to use a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Proxy&lt;/code&gt;&lt;/a&gt; object (at the time of writing, &lt;a href=&quot;https://caniuse.com/#search=proxy&quot;&gt;global support is at 92.76%&lt;/a&gt;) to enable chaining of style changes. Turns out, it’s relatively easy. We’ll walk through how to create a light-weight Proxy handler that will enable us to shorten the code above to this:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.menu&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#fff&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;backgroundColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#000&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’ll use roughly the same strategy as jQuery does: we’ll fetch the style object of an element and wrap it with a Proxy in order to intercept (trap) all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get&lt;/code&gt; calls to that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;style&lt;/code&gt; object, take the accessed property and update its value if a value is passed, and then return the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Proxy&lt;/code&gt; handler wrapping the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;style&lt;/code&gt; object again, enabling us to build an infinite chain of commands.&lt;/p&gt;

&lt;p&gt;Since we’ll repurpose the get method to also act as a setter, we’ll retain the get functionality by returning the value of a property if you don’t pass any arguments to the function (i.e. you’ll get a value through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;style(&quot;.menu&quot;).color()&lt;/code&gt; rather than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;style(&quot;.menu&quot;).color&lt;/code&gt;). Here’s the gist of the technique:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleProxy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s break it down, and quickly walk through how a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Proxy&lt;/code&gt; works.&lt;/p&gt;

&lt;h2 id=&quot;its-a-trap&quot;&gt;It’s a trap!&lt;/h2&gt;

&lt;p&gt;The first aspects to understand about using a Proxy are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handlers&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;traps&lt;/code&gt;. We can create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handler&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;trap&lt;/code&gt; a series of operations, e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set()&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply()&lt;/code&gt;. In essence, we’ll get a chance to intercept those operations on the object we’re wrapping and do with them whatever we want—we can return different values depending on some logic, or simply forward the operation to the original target.&lt;/p&gt;

&lt;p&gt;As a simple example, we can always return the same value regardless of what property you try to access, even if no property has been set on the original object:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;hodor&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;person&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Wylis&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; 
&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;proxied&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// &quot;Wylis&quot;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;proxied&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// &quot;hodor&quot;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;proxied&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//  &quot;hodor&quot;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;proxied&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;favoriteFood&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// &quot;hodor&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;always-return-a-function&quot;&gt;Always return a function&lt;/h2&gt;

&lt;p&gt;This enables us to completely change how an object works. To enable chaining for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;style&lt;/code&gt; object, we’ll expand &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get&lt;/code&gt; to also work as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set&lt;/code&gt;. We’ll still only trap &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get&lt;/code&gt;, but rather than returning the value of a property when it’s accessed we’ll return a function that returns the value of the property only if the function is invoked without any arguments. If an argument is passed, we’ll use it to update that property’s value.&lt;/p&gt;

&lt;p&gt;Let’s start by just getting the basics into place. Let’s create a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handler&lt;/code&gt; called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getProxy&lt;/code&gt;, and create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get&lt;/code&gt; trap, where we always return a function. Thus if we just log a property, we’ll get a function. But if we invoke that function, we’ll see what it returns (in this case “test”):&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getProxy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;proxied&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({},&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;proxied&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// Our function: (argument) =&amp;gt; { return &quot;test&quot;; }&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;proxied&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The value: &quot;test&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;use-the-function-to-get-and-set-values&quot;&gt;Use the function to get and set values&lt;/h2&gt;

&lt;p&gt;Inside our new function, we can check if an argument is being passed to it when it’s invoked. If something is passed, we can use that argument to update the property. If no arguments are passed we can simply return the value of that property, basically maintaining the original &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get&lt;/code&gt; functionality while expanding it with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set&lt;/code&gt; option.&lt;/p&gt;

&lt;p&gt;Let’s create a new Proxy, this time called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;styleProxy&lt;/code&gt;. We’ll check if something is being passed to it, and get and set accordingly. Our proxy handler is also being passed an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;object&lt;/code&gt; (the object we’re wrapping and intercepting) and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;property&lt;/code&gt; argument (the property we’re operating on), and we can use these two to operate on the original target.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleProxy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// &quot;object&quot; is the object that we're wrapping&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// &quot;property&quot; is the property of the object that we're accessing&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// &quot;value&quot; is what we passed to the function&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Let's use these three to update the style object:&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// If no arguments were passed, simply return the&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// value of that property:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This enables our handler’s get method to act both as a setter and getter:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.menu&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#fff&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Gets a function which updates color to &quot;#fff&quot;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.menu&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;// No arguments passed, just returns &quot;#fff&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that since we’re not creating a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;trap&lt;/code&gt; for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set&lt;/code&gt; operation, we can still set a property’s value by assigning a value to it directly:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Works like expected&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.menu&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#fff&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;return-the-style-object-wrapped-in-a-proxy&quot;&gt;Return the style object wrapped in a proxy&lt;/h2&gt;

&lt;p&gt;Now that we’re in control of what’s being returned after we update a property, we can simply return the original &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;style&lt;/code&gt; object wrapped in our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Proxy&lt;/code&gt; handler if an argument is passed, completing our chaining method:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleProxy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Return the original target, wrapped in the same Proxy handler&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When we use method chaining, then, this is what’s happening behind the scenes:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.menu&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;              &lt;span class=&quot;c1&quot;&gt;// Returns the style object in a Proxy&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#fff&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;// Updates color and returns a Proxy&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;backgroundColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#000&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Updates bgColor and returns a Proxy&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;// ... and so on so forth&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here’s the solution in full:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleProxy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I can’t confidently say that I recommend this approach—and I won’t be using it on this site anytime soon due to the just-too-low browser support, but I find it fascinating how bendable JavaScript is, and how with the Proxy API we can go even further.&lt;/p&gt;
</description>
				<pubDate>Thu, 19 Sep 2019 07:50:00 +0000</pubDate>
				<link>https://tobiasahlin.com/blog/chaining-styles-with-proxy/</link>
				<guid isPermaLink="true">https://tobiasahlin.com/blog/chaining-styles-with-proxy/</guid>
			</item>
		
			<item>
				<title>Smoother &amp; sharper shadows with layered box-shadows</title>
				<description>&lt;div class=&quot;blog-banner&quot;&gt;
  &lt;div class=&quot;blog-banner-content&quot;&gt;
    &lt;div class=&quot;blog-traditional-shadow-box&quot;&gt;Default&lt;/div&gt;
    &lt;div class=&quot;blog-realistic-shadow-box&quot;&gt;Smooth&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
  .blog-traditional-shadow-box {
    background-color: #fff;
    line-height: 76px;
    border-radius: 3px;
    color: #333;
    margin-right: 15px;
    display: inline-block;
    width: 100px;
    height: 80px;
    box-shadow: 0 6px 6px rgba(16,27,30,0.4);
  }
  .blog-realistic-shadow-box {
    background-color: #fff;
    line-height: 76px;
    border-radius: 3px;
    margin-left: 15px;
    display: inline-block;
    color: #333;
    width: 100px;
    height: 80px;
    box-shadow: 0 1px 1px rgba(16,27,30,0.15), 
                0 2px 2px rgba(16,27,30,0.15), 
                0 4px 4px rgba(16,27,30,0.15), 
                0 8px 8px rgba(16,27,30,0.15), 
                0 16px 16px rgba(16,27,30,0.15);
  }
  .blog-shadow-big {
    width: 200px;
    height: 120px;
    padding-top: 40px;
    line-height: 20px;
    margin-bottom: 30px;
    margin-top: 30px;
    box-sizing: border-box;
    margin-left: 15px;
    margin-right: 15px;
  }
  
  .blog-shadow-label {
    font-size: 12px;
    color: #666;
    display: block;
  }
&lt;/style&gt;

&lt;!--more--&gt;

&lt;p&gt;As light hits an object and a shadow is cast, the shadow can take on a myriad of unique characteristics. If you try to capture the subtleties of a real shadow with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;box-shadow&lt;/code&gt; then, well, you’re pretty much out of luck. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;box-shadow&lt;/code&gt; CSS property isn’t exactly built to encourage expressiveness. It essentially produces a blurred silhouette of an object—you can change its offset, blur radius, spread, and color, but that’s it. We can’t get anywhere near to expressing the complexities and nuances of shadows in real life.&lt;/p&gt;

&lt;p&gt;But with a simple CSS technique, we can expand our range of options. If we use layered &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;box-shadow&lt;/code&gt;s we can get more fine-grained control over how shadows are rendered:&lt;/p&gt;

&lt;style&gt;
  .blog-shadow-6 { box-shadow: 0 6px 6px rgba(0,0,0,0.4); }
  
  .blog-shadow-long {
    box-shadow: 0 1px 1px rgba(0,0,0,0.12), 0 2px 2px rgba(0,0,0,0.12), 0 4px 4px rgba(0,0,0,0.12), 0 8px 8px rgba(0,0,0,0.12), 0 16px 16px rgba(0,0,0,0.12);
  }
&lt;/style&gt;

&lt;div class=&quot;post-content-wrapper center&quot;&gt;
  &lt;div class=&quot;blog-traditional-shadow-box blog-shadow-big blog-shadow-6&quot;&gt;box-shadow
      &lt;span class=&quot;blog-shadow-label&quot;&gt;0 6px 6px rgba(0,0,0,0.2);&lt;/span&gt;
  &lt;/div&gt;
  &lt;div class=&quot;blog-realistic-shadow-box blog-shadow-big blog-shadow-long&quot;&gt;Layered box-shadows
    &lt;span class=&quot;blog-shadow-label&quot;&gt;gradually increasing offset/blur&lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Look at how square and clumsy the default &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;box-shadow&lt;/code&gt; effect (first box) looks compared to the layered &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;box-shadow&lt;/code&gt; (second box). We can achieve this effect by creating multiple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;box-shadows&lt;/code&gt; (separating each shadow with a comma), and increasing the offset and blur for every shadow (the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;box-shadow&lt;/code&gt; syntax is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X-offset Y-offset blur color&lt;/code&gt;):&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;/* Default box-shadow */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.box&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;/* Create smoother box-shadows by layering multiple
 * shadows with gradually increasing radius and offset */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.shadow-5&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;16px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;16px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This simple layering technique gives us more control over the rendering of shadows, and with it we can fine-tune sharpness, distance, and spread. You can for example increase or decrease the number of shadows to create a smaller or larger spread. (Note that if you increase the number of layers you’ll have to decrease the alpha value for each layer if you wish to keep the strength somewhat the same.)&lt;/p&gt;

&lt;style&gt;
  
  .blog-shadow-medium {
    box-shadow: 0 1px 1px rgba(0,0,0,0.15), 0 2px 2px rgba(0,0,0,0.15), 0 4px 4px rgba(0,0,0,0.15), 0 8px 8px rgba(0,0,0,0.15);
  }

  .blog-shadow-extra-long {
    box-shadow: 0 1px 1px rgba(0,0,0,0.11), 0 2px 2px rgba(0,0,0,0.11), 0 4px 4px rgba(0,0,0,0.11), 0 8px 8px rgba(0,0,0,0.11), 0 16px 16px rgba(0,0,0,0.11), 0 32px 32px rgba(0,0,0,0.11);
  }
&lt;/style&gt;

&lt;div class=&quot;post-content-wrapper center&quot;&gt;
  &lt;div class=&quot;blog-realistic-shadow-box blog-shadow-big blog-shadow-medium&quot;&gt;Layered box-shadows
    &lt;span class=&quot;blog-shadow-label&quot;&gt;4 shadows with 15% alpha&lt;/span&gt;
  &lt;/div&gt;
  &lt;div class=&quot;blog-realistic-shadow-box blog-shadow-big blog-shadow-extra-long&quot;&gt;Layered box-shadows
    &lt;span class=&quot;blog-shadow-label&quot;&gt;6 shadows with 11% alpha&lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.shadow-4&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.shadow-6&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;16px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;16px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Controlling sharpness is as easy as controlling spread, but we can use both the alpha value and the blur value of each layer to change the &lt;em&gt;concentration of depth&lt;/em&gt; and the &lt;em&gt;blur radius&lt;/em&gt; of the shadow respectively.&lt;/p&gt;

&lt;p&gt;The examples above use the same alpha value for all layers, but we can let the alpha value decrease or increase with every layer to create more or less diffuse shadows. For the more concentrated shadow below, the innermost shadow (with the least offset and blur) has the highest alpha value, and it decreases with every layer. The opposite is true for the more diffuse shadow of the second box, where the innermost layer has the lowest alpha value:&lt;/p&gt;

&lt;style&gt;
  
  .blog-shadow-sharp {
    box-shadow: 0 1px 1px rgba(0,0,0,0.25), 
                0 2px 2px rgba(0,0,0,0.20), 
                0 4px 4px rgba(0,0,0,0.15), 
                0 8px 8px rgba(0,0,0,0.10),
                0 16px 16px rgba(0,0,0,0.05);
  }

  .blog-shadow-soft {
    box-shadow: 0 1px 1px rgba(0,0,0,0.08), 
                0 2px 2px rgba(0,0,0,0.12), 
                0 4px 4px rgba(0,0,0,0.16), 
                0 8px 8px rgba(0,0,0,0.20);
  }

&lt;/style&gt;

&lt;div class=&quot;post-content-wrapper center&quot;&gt;
  &lt;div class=&quot;blog-realistic-shadow-box blog-shadow-big blog-shadow-sharp&quot;&gt;Sharp
    &lt;span class=&quot;blog-shadow-label&quot;&gt;Shadows with decreasing alpha&lt;/span&gt;
  &lt;/div&gt;
  &lt;div class=&quot;blog-realistic-shadow-box blog-shadow-big blog-shadow-soft&quot;&gt;Diffuse
    &lt;span class=&quot;blog-shadow-label&quot;&gt;Shadows with increasing alpha&lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.blog-shadow-sharp&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;16px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;16px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.blog-shadow-diffuse&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can also increase the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;blur&lt;/code&gt; in higher incremenents, to increase the spread and create softer, almost dreamy, effects:&lt;/p&gt;

&lt;style&gt;
  
  .blog-shadow-softer {
    box-shadow: 0 1px 2px rgba(0,0,0,0.07), 
                0 2px 4px rgba(0,0,0,0.07), 
                0 4px 8px rgba(0,0,0,0.07), 
                0 8px 16px rgba(0,0,0,0.07),
                0 16px 32px rgba(0,0,0,0.07), 
                0 32px 64px rgba(0,0,0,0.07);
  }

&lt;/style&gt;

&lt;div class=&quot;post-content-wrapper center&quot;&gt;
  &lt;div class=&quot;blog-realistic-shadow-box blog-shadow-big blog-shadow-softer&quot;&gt;Dreamy soft
    &lt;span class=&quot;blog-shadow-label&quot;&gt;Higher blur increase&lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.blog-shadow-dreamy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.07&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.07&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.07&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;16px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.07&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;16px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.07&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;64px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.07&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally, we can control the distance by decoupling the blur radius and Y-offset, and increase the offset in bigger or smaller increments:&lt;/p&gt;

&lt;style&gt;
  
.blog-shadow-distance-short {
  box-shadow: 0 1px 1px rgba(0,0,0,0.11), 
              0 2px 2px rgba(0,0,0,0.11), 
              0 4px 4px rgba(0,0,0,0.11), 
              0 6px 8px rgba(0,0,0,0.11),
              0 8px 16px rgba(0,0,0,0.11);
}

.blog-shadow-distance-long {
  box-shadow: 0 2px 1px rgba(0,0,0,0.09), 
              0 4px 2px rgba(0,0,0,0.09), 
              0 8px 4px rgba(0,0,0,0.09), 
              0 16px 8px rgba(0,0,0,0.09),
              0 32px 16px rgba(0,0,0,0.09);
}

&lt;/style&gt;

&lt;div class=&quot;post-content-wrapper center&quot;&gt;
  &lt;div class=&quot;blog-realistic-shadow-box blog-shadow-big blog-shadow-distance-short&quot;&gt;Shorter
    &lt;span class=&quot;blog-shadow-label&quot;&gt;Shadows with smaller distances&lt;/span&gt;
  &lt;/div&gt;
  &lt;div class=&quot;blog-realistic-shadow-box blog-shadow-big blog-shadow-distance-long&quot;&gt;Longer
    &lt;span class=&quot;blog-shadow-label&quot;&gt;Shadows with larger distances&lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.shadow-shorter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;6px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;16px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.shadow-longer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.09&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.09&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.09&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;16px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.09&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32px&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;16px&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rgba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.09&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Which combination of all of these techniques to use is of course highly dependent on the context that you’re working in, but with layered shadows we can at the very least gain some more control to help us achieve our desired look and feel.&lt;/p&gt;

&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/how-to-animate-box-shadow/&quot;&gt;Learn how to minimize repaints while animating box-shadows&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://twitter.com/funkensturm&quot;&gt;Philipp Brumm&lt;/a&gt; wrote a &lt;a href=&quot;https://brumm.af/shadows&quot;&gt;smooth box shadow generator inspired by this article&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
				<pubDate>Thu, 19 Sep 2019 07:50:00 +0000</pubDate>
				<link>https://tobiasahlin.com/blog/layered-smooth-box-shadows/</link>
				<guid isPermaLink="true">https://tobiasahlin.com/blog/layered-smooth-box-shadows/</guid>
			</item>
		
			<item>
				<title>Cheat sheet for moving from jQuery to vanilla JavaScript</title>
				<description>&lt;div class=&quot;blog-banner&quot;&gt;
  &lt;div class=&quot;blog-banner-content&quot;&gt;
    &lt;svg class=&quot;blog-banner-jquery&quot; width=&quot;391&quot; height=&quot;112&quot; viewBox=&quot;0 0 3914 1124&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
  &lt;path class=&quot;jquery-logo-letter jquery-logo-j-dot&quot; d=&quot;M513.764 186.355H346.729C337.938 186.355 330.905 188.114 329.147 196.904L299.256 327.006C297.498 334.039 302.773 341.071 311.564 341.071H471.566C480.357 341.071 487.39 334.039 489.148 325.248L517.281 193.388C517.281 193.388 520.797 186.355 513.764 186.355Z&quot; fill=&quot;#fff&quot; /&gt;
  &lt;path class=&quot;jquery-logo-letter jquery-logo-j&quot; d=&quot;M301.014 383.27C292.223 383.27 285.19 390.302 283.432 397.335L260.574 497.548L209.584 727.864C209.584 727.864 183.211 849.175 179.694 857.965C179.694 857.965 156.837 945.872 104.089 942.356C79.4731 940.598 51.3409 935.323 51.3409 935.323C35.5166 930.049 35.5166 945.872 33.7583 954.663L0.351398 1097.07C-1.40686 1104.1 3.86789 1111.14 10.9009 1112.89C10.9009 1112.89 82.9897 1123.44 133.979 1123.44H142.771C267.607 1123.44 334.421 1049.6 376.619 849.175L425.851 615.343L471.565 399.093C473.324 392.06 468.049 383.27 461.016 383.27&quot; fill=&quot;#fff&quot; /&gt;
  &lt;path class=&quot;jquery-logo-letter jquery-logo-q&quot; d=&quot;M1245.2 662.816C1245.2 662.816 1324.32 471.18 1341.91 362.175C1366.52 214.492 1292.67 0 1006.08 0C722.998 0 599.919 203.943 552.446 427.226C504.973 650.509 566.512 845.662 849.592 843.904H1280.37C1289.16 843.904 1296.19 836.871 1297.95 829.839L1334.87 690.946C1336.63 683.914 1331.36 676.881 1324.32 676.881H1289.16H1253.99C1246.96 676.881 1243.44 671.607 1243.44 666.332C1245.2 666.332 1245.2 664.574 1245.2 662.816ZM1097.51 546.779L1065.86 657.542C1064.1 664.574 1055.31 669.849 1046.52 669.849H879.483C752.888 669.849 721.239 571.393 752.888 425.468C784.537 276.027 844.318 184.604 969.154 174.055C1139.71 161.748 1174.87 281.301 1132.67 420.194L1097.51 546.779Z&quot; fill=&quot;#fff&quot; /&gt;
  &lt;path class=&quot;jquery-logo-letter jquery-logo-u&quot; d=&quot;M2064.55 186.355H1908.06C1899.27 186.355 1892.24 189.872 1890.48 196.904L1839.49 437.768L1788.5 668.084C1786.74 675.116 1779.71 675.116 1770.92 675.116H1668.94C1566.96 675.116 1579.27 611.824 1600.37 515.126C1600.37 513.368 1665.42 196.904 1665.42 196.904C1667.18 189.872 1661.91 186.355 1653.12 186.355H1505.42C1496.63 186.355 1489.6 189.872 1487.84 196.904L1428.06 515.126C1398.17 687.423 1398.17 838.623 1596.85 843.897C1600.37 843.897 1911.58 843.897 1911.58 843.897C1920.37 843.897 1927.41 840.381 1929.16 833.348L1997.74 513.368L2064.55 193.388C2064.55 193.388 2068.07 186.355 2064.55 186.355Z&quot; fill=&quot;#fff&quot; /&gt;
  &lt;path class=&quot;jquery-logo-letter jquery-logo-e&quot; d=&quot;M2458.4 184.604C2177.08 184.604 2110.27 358.659 2073.34 529.198C2036.42 705.011 2039.94 843.903 2330.05 843.903H2340.6C2456.64 843.903 2595.55 843.903 2595.55 843.903C2602.58 843.903 2611.37 836.871 2613.13 828.08L2641.26 717.318C2643.02 710.285 2637.74 706.769 2628.95 706.769H2366.97C2272.03 706.769 2238.62 676.881 2242.14 611.83C2242.14 604.797 2250.93 585.458 2257.96 585.458H2660.6C2678.18 585.458 2678.18 574.909 2678.18 574.909C2722.14 392.063 2723.9 184.604 2458.4 184.604ZM2532.25 460.63C2532.25 469.421 2504.12 467.663 2504.12 467.663L2286.09 465.905C2279.06 465.905 2275.54 455.356 2275.54 448.323C2275.54 448.323 2275.54 439.533 2277.3 437.775C2294.88 379.756 2344.12 346.352 2425 346.352C2514.67 346.352 2534.01 390.305 2534.01 441.291&quot; fill=&quot;#fff&quot; /&gt;
  &lt;path class=&quot;jquery-logo-letter jquery-logo-r&quot; d=&quot;M3370.94 330.522L3355.11 260.197C3342.81 209.211 3305.88 186.355 3223.24 186.355H2875.11C2866.32 186.355 2859.28 189.872 2857.53 198.662L2725.66 824.558C2723.9 833.349 2723.9 838.623 2723.9 842.139C2725.66 845.655 2739.72 845.655 2748.51 845.655H2869.83C2878.63 845.655 2892.69 845.655 2896.21 843.897C2901.48 842.139 2903.24 829.832 2905 822.8L2947.2 603.033L2999.95 358.653C3001.7 351.62 3008.74 344.587 3017.53 344.587H3362.15C3367.42 344.587 3372.7 337.555 3370.94 330.522Z&quot; fill=&quot;#fff&quot; /&gt;
  &lt;path class=&quot;jquery-logo-letter jquery-logo-y&quot; d=&quot;M3861.49 75.5967C3852.7 75.5967 3708.53 75.5967 3708.53 75.5967C3699.73 75.5967 3690.94 84.3873 3685.67 91.4199L3416.65 485.242C3411.38 492.274 3406.1 492.274 3404.35 483.484L3385.01 397.335C3383.25 390.302 3374.46 383.27 3367.42 383.27H3195.11C3186.32 383.27 3182.81 390.302 3184.56 397.335L3261.93 668.087C3263.69 675.12 3263.69 689.185 3261.93 696.218L3225 833.352C3223.25 840.385 3228.52 843.901 3235.55 843.901H3406.1C3414.9 843.901 3421.93 842.143 3423.69 833.352L3460.61 694.459C3462.37 687.427 3467.64 676.878 3472.92 669.846L3910.73 89.6617C3916 82.6292 3914.24 75.5967 3907.21 75.5967H3861.49Z&quot; fill=&quot;#fff&quot; /&gt;
&lt;/svg&gt;
    &lt;div class=&quot;blog-banner-jquery-hole&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
  .blog-banner-jquery {
    width: 200px;
    height: 100px;
    position: relative;
    z-index: 3;
  }

  .blog-banner-jquery-hole {
    background-color: rgba(0,0,0,0.3);
    width: 90px;
    height: 90px;
    border-radius: 50%;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    margin: auto;
    z-index: 1;
    transform: scale(0);
  }
&lt;/style&gt;

&lt;script&gt;
var removeJqueryTimeline = anime.timeline({ loop: true });
removeJqueryTimeline
  .add({
    targets: '.blog-banner-jquery-hole',
    scaleY: [0,0],
    scaleX: [0,0],
    duration: 100
  })
  .add({
    targets: '.blog-banner-jquery-hole',
    scaleY: 1,
    scaleX: 1,
    duration: 900,
    delay: 200
  })
  .add({
    targets: '.jquery-logo-letter',
    translateX: &quot;2000px&quot;,
    translateY: &quot;500px&quot;,
    scaleY: 0,
    scaleX: 0,
    opacity: 0,
    easing: &quot;easeInExpo&quot;,
    delay: function(el, i) { return i*70 },
    duration: 500
  })
  .add({
    targets: '.blog-banner-jquery-hole',
    scaleY: 1.4,
    scaleX: 1.4,
    duration: 600,
    offset: &quot;-=520&quot;
  })
  .add({
    targets: '.blog-banner-jquery-hole',
    scaleY: 0,
    scaleX: 0,
    duration: 600,
    easing: &quot;easeInExpo&quot;
  })
  .add({
    targets: '.jquery-logo-letter',
    translateX: [0,0],
    translateY: [0,0],
    scaleY: [1,1],
    scaleX: [1,1],
    opacity: [0,1],
    easing: &quot;easeOutExpo&quot;,
    delay: function(el, i) { return 1400+i*70 },
    duration: 1200
  });
app.animations.track(removeJqueryTimeline, document.querySelector(&quot;.blog-banner-jquery-hole&quot;));
&lt;/script&gt;

&lt;!--more--&gt;

&lt;p&gt;jQuery is still a useful and pragmatic library, but chances are increasingly that you’re not dependent on using it in your projects to accomplish basic tasks like selecting elements, styling them, animating them, and fetching data—things that jQuery was great at. With broad browser support of ES6 (&lt;a href=&quot;https://caniuse.com/#feat=es6&quot;&gt;over  96%&lt;/a&gt; at the time of writing), now is probably a good time to move away from jQuery.&lt;/p&gt;

&lt;p&gt;I recently removed jQuery from this blog and found myself googling for some of the patterns over and over again. To spare you the time, I’ve compiled this practical reference guide with some of the most common jQuery patterns and their equivalents in JavaScript. We’ll cover how to move over to vanilla JavaScript from these concepts and functions:&lt;/p&gt;

&lt;div class=&quot;post-jumper&quot;&gt;
  &lt;a href=&quot;#selecting-elements&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;svg width=&quot;100&quot; height=&quot;22&quot; viewBox=&quot;0 0 100 22&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&lt;rect x=&quot;0.5&quot; y=&quot;21.5&quot; width=&quot;21&quot; height=&quot;12&quot; rx=&quot;0.5&quot; transform=&quot;rotate(-90 0.5 21.5)&quot; fill=&quot;#E1D9E7&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;rect x=&quot;17.5&quot; y=&quot;21.5&quot; width=&quot;21&quot; height=&quot;12&quot; rx=&quot;0.5&quot; transform=&quot;rotate(-90 17.5 21.5)&quot; fill=&quot;#88619F&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;rect x=&quot;35.5&quot; y=&quot;21.5&quot; width=&quot;21&quot; height=&quot;12&quot; rx=&quot;0.5&quot; transform=&quot;rotate(-90 35.5 21.5)&quot; fill=&quot;#E1D9E7&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;rect x=&quot;52.5&quot; y=&quot;21.5&quot; width=&quot;21&quot; height=&quot;12&quot; rx=&quot;0.5&quot; transform=&quot;rotate(-90 52.5 21.5)&quot; fill=&quot;#E1D9E7&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;rect x=&quot;70.5&quot; y=&quot;21.5&quot; width=&quot;21&quot; height=&quot;12&quot; rx=&quot;0.5&quot; transform=&quot;rotate(-90 70.5 21.5)&quot; fill=&quot;#E1D9E7&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;rect x=&quot;87.5&quot; y=&quot;21.5&quot; width=&quot;21&quot; height=&quot;12&quot; rx=&quot;0.5&quot; transform=&quot;rotate(-90 87.5 21.5)&quot; fill=&quot;#E1D9E7&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;/svg&gt;

    &lt;span class=&quot;post-jumper-title&quot;&gt;Selecting elements&lt;/span&gt;
  &lt;/a&gt;  
  &lt;a href=&quot;#working-with-events&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;svg style=&quot;position: relative; bottom: -6px&quot; width=&quot;57&quot; height=&quot;40&quot; viewBox=&quot;0 0 57 40&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&lt;rect x=&quot;0.5&quot; y=&quot;0.5&quot; width=&quot;53&quot; height=&quot;26&quot; rx=&quot;3.5&quot; fill=&quot;#E1D9E7&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M57 29.9306L36 15L40.9 40L47.0676 31.1932L57 29.9306Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M36.4123 11.9828V4.19336M39.9825 15.4023H47.772M25.0527 15.4023L33.4913 15.4023M31 20.9653L33.8158 18.1495M33.8158 12.632L31 9.81612M39.3334 12.632L42.5 9.46533&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;/svg&gt;

    &lt;span class=&quot;post-jumper-title&quot;&gt;Events&lt;/span&gt;
  &lt;/a&gt;
  &lt;a href=&quot;#styling-elements&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;svg width=&quot;80&quot; height=&quot;25&quot; viewBox=&quot;0 0 80 25&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&lt;path d=&quot;M4.52402 20.2798C4.52402 23.3038 6.14802 24.2558 9.73202 24.2558H11.888V22.0718H10.74C8.41602 22.0718 7.88402 21.6798 7.88402 20.1118C7.88402 18.5998 8.02402 17.2558 8.02402 15.5478C8.02402 13.4198 7.21202 12.6078 5.22402 12.2718V12.1598C7.21202 11.8238 8.02402 11.0118 8.02402 8.88378C8.02402 7.23178 7.88402 5.80378 7.88402 4.31978C7.88402 2.75178 8.41602 2.35978 10.74 2.35978H11.888V0.175781H9.73202C6.14802 0.175781 4.52402 1.12778 4.52402 4.15178C4.52402 6.11178 4.80402 7.20378 4.80402 8.93978C4.80402 9.91978 3.99202 10.9558 0.968018 11.0118V13.4198C3.99202 13.4758 4.80402 14.5118 4.80402 15.4918C4.80402 17.2558 4.52402 18.2918 4.52402 20.2798Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M19.9411 17.0598C19.9411 18.9078 21.2571 20.3358 23.1891 20.3358C25.1211 20.3358 26.4371 18.9078 26.4371 17.0598C26.4371 15.2118 25.1211 13.7558 23.1891 13.7558C21.2571 13.7558 19.9411 15.2118 19.9411 17.0598Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M36.7301 17.0598C36.7301 18.9078 38.0461 20.3358 39.9781 20.3358C41.9101 20.3358 43.2261 18.9078 43.2261 17.0598C43.2261 15.2118 41.9101 13.7558 39.9781 13.7558C38.0461 13.7558 36.7301 15.2118 36.7301 17.0598Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M53.5192 17.0598C53.5192 18.9078 54.8352 20.3358 56.7672 20.3358C58.6992 20.3358 60.0152 18.9078 60.0152 17.0598C60.0152 15.2118 58.6992 13.7558 56.7672 13.7558C54.8352 13.7558 53.5192 15.2118 53.5192 17.0598Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M68.0963 22.0718V24.2558H70.2523C73.8363 24.2558 75.4603 23.3038 75.4603 20.2798C75.4603 18.2918 75.1523 17.2558 75.1523 15.4918C75.1523 14.5118 75.9643 13.4758 79.0163 13.4198V11.0118C75.9643 10.9558 75.1523 9.91978 75.1523 8.93978C75.1523 7.20378 75.4603 6.11178 75.4603 4.15178C75.4603 1.12778 73.8363 0.175781 70.2523 0.175781H68.0963V2.35978H69.2443C71.5403 2.35978 72.0723 2.75178 72.0723 4.31978C72.0723 5.80378 71.9603 7.23178 71.9603 8.88378C71.9603 11.0118 72.7443 11.8238 74.7603 12.1598V12.2718C72.7443 12.6078 71.9603 13.4198 71.9603 15.5478C71.9603 17.2558 72.0723 18.5998 72.0723 20.1118C72.0723 21.6798 71.5403 22.0718 69.2443 22.0718H68.0963Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;/svg&gt;

    &lt;span class=&quot;post-jumper-title&quot;&gt;.css()&lt;/span&gt;
  &lt;/a&gt;
  &lt;a href=&quot;#document-ready&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;svg width=&quot;41&quot; height=&quot;49&quot; viewBox=&quot;0 0 41 49&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&lt;rect x=&quot;4.5&quot; y=&quot;3.5&quot; width=&quot;36&quot; height=&quot;45&quot; rx=&quot;0.5&quot; fill=&quot;#E1D9E7&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;rect x=&quot;0.5&quot; y=&quot;0.5&quot; width=&quot;36&quot; height=&quot;45&quot; rx=&quot;0.5&quot; fill=&quot;#E1D9E7&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M12 22L16.5 26.5L25 18&quot; stroke=&quot;#88619F&quot; stroke-width=&quot;3&quot; /&gt;
&lt;/svg&gt;

    &lt;span class=&quot;post-jumper-title&quot;&gt;Document ready&lt;/span&gt;
  &lt;/a&gt;
  &lt;a href=&quot;#working-with-classes&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;svg width=&quot;92&quot; height=&quot;37&quot; viewBox=&quot;0 0 92 37&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&lt;path d=&quot;M0.711243 12.9002C0.711243 14.2202 1.65124 15.2402 3.03124 15.2402C4.41124 15.2402 5.35124 14.2202 5.35124 12.9002C5.35124 11.5802 4.41124 10.5402 3.03124 10.5402C1.65124 10.5402 0.711243 11.5802 0.711243 12.9002Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M20.7234 1.28023C19.8834 1.00023 18.8634 0.740234 17.7234 0.740234C14.6234 0.740234 13.2834 2.54023 13.2834 4.82024V5.08024L10.6634 5.20024V7.38024H13.2834V15.0002H16.2234V7.38024H19.6434V5.08024H16.2234V4.80023C16.2234 3.60023 16.8234 3.06024 18.0834 3.06024C18.8434 3.06024 19.5434 3.20023 20.1634 3.44024L20.7234 1.28023Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M21.9556 10.0402C21.9556 13.3402 24.3956 15.2402 27.0156 15.2402C29.6356 15.2402 32.0756 13.3402 32.0756 10.0402C32.0756 6.74024 29.6356 4.84024 27.0156 4.84024C24.3956 4.84024 21.9556 6.74024 21.9556 10.0402ZM24.9756 10.0402C24.9756 8.32024 25.6556 7.22023 27.0156 7.22023C28.3756 7.22023 29.0556 8.32024 29.0556 10.0402C29.0556 11.7602 28.3756 12.8602 27.0156 12.8602C25.6556 12.8602 24.9756 11.7602 24.9756 10.0402Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M34.3478 10.0402C34.3478 13.3402 36.7478 15.2402 39.8678 15.2402C41.2278 15.2402 42.7678 14.7802 43.9678 13.7802L42.7678 11.9202C42.0678 12.4202 41.1878 12.8602 40.1478 12.8602C38.5078 12.8602 37.3678 11.7602 37.3678 10.0402C37.3678 8.32024 38.5478 7.22023 40.2478 7.22023C40.9878 7.22023 41.6878 7.46024 42.4478 8.00024L43.8078 6.18023C42.9678 5.40023 41.6478 4.84024 40.0878 4.84024C37.0278 4.84024 34.3478 6.74024 34.3478 10.0402Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M55.5 5.08024H52.56V11.6002C51.88 12.4802 51.36 12.7402 50.62 12.7402C49.52 12.7402 49.18 12.1402 49.18 10.8202V5.08024H46.24V11.2002C46.24 13.7002 47.2 15.2402 49.46 15.2402C50.88 15.2402 51.92 14.5802 52.8 13.5802H52.88L53.1 15.0002H55.5V5.08024Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M58.0522 13.7202C59.3122 14.5602 61.1322 15.2402 62.9122 15.2402C66.0922 15.2402 67.7922 13.8402 67.7922 12.0402C67.7922 10.3202 66.0922 9.58023 64.1322 9.06024C62.7322 8.70023 61.5922 8.40023 61.5922 7.80023C61.5922 7.30023 62.0722 7.02024 63.3122 7.02024C64.3522 7.02024 65.3122 7.42024 66.2122 7.96023L67.5322 6.20024C66.4922 5.54024 65.0122 4.84024 63.2522 4.84024C60.4122 4.84024 58.6722 6.10023 58.6722 7.94024C58.6722 9.52024 60.4722 10.3602 62.2122 10.8402C63.8122 11.2802 64.8722 11.6202 64.8722 12.2202C64.8722 12.7402 64.3122 13.0602 62.9722 13.0602C61.6522 13.0602 60.5122 12.6002 59.3722 11.8802L58.0522 13.7202Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M70.0844 10.0402C70.0844 13.3202 72.5044 15.2402 75.5844 15.2402C76.9044 15.2402 78.3844 14.8002 79.5044 14.0802L78.5444 12.3202C77.6644 12.7602 76.8844 13.0002 75.9844 13.0002C74.5244 13.0002 73.3044 12.3802 73.1044 10.9002H79.7844C79.8244 10.6602 79.9044 10.1202 79.9044 9.60023C79.9044 6.90023 78.3044 4.84024 75.2444 4.84024C72.6044 4.84024 70.0844 6.80024 70.0844 10.0402ZM73.0644 8.96024C73.3244 7.68024 74.2444 7.08024 75.3044 7.08024C76.6444 7.08024 77.2444 7.84024 77.2444 8.96024H73.0644Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M81.9166 10.0402C81.9166 13.2802 83.5766 15.2402 86.0966 15.2402C87.0966 15.2402 88.1166 14.7002 88.8566 13.9802H88.9166L89.1366 15.0002H91.5366V0.980235H88.5966V4.36024L88.6966 5.90024C87.9966 5.26024 87.2966 4.84024 86.1566 4.84024C83.9966 4.84024 81.9166 6.80024 81.9166 10.0402ZM84.9366 10.0002C84.9366 8.12024 85.8566 7.24024 86.9366 7.24024C87.5166 7.24024 88.0566 7.42024 88.5966 7.90024V11.9202C88.0766 12.5802 87.5166 12.8402 86.8566 12.8402C85.6366 12.8402 84.9366 11.9602 84.9366 10.0002Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M0.711243 33.9005C0.711243 35.2205 1.65124 36.2405 3.03124 36.2405C4.41124 36.2405 5.35124 35.2205 5.35124 33.9005C5.35124 32.5805 4.41124 31.5405 3.03124 31.5405C1.65124 31.5405 0.711243 32.5805 0.711243 33.9005Z&quot; fill=&quot;#88619F&quot; fill-opacity=&quot;0.468&quot; /&gt;
&lt;path d=&quot;M10.4634 36.0005H12.7634L13.0034 34.9205H13.0834C13.9034 35.7805 14.8634 36.2405 15.7834 36.2405C18.0034 36.2405 20.0834 34.2805 20.0834 30.8605C20.0834 27.8205 18.5634 25.8405 16.0834 25.8405C15.1234 25.8405 14.1034 26.2605 13.3234 26.9805L13.4034 25.4205V21.9805H10.4634V36.0005ZM13.4034 33.1805V29.1605C14.0234 28.5205 14.6034 28.2405 15.2434 28.2405C16.4834 28.2405 17.0634 29.1405 17.0634 30.9205C17.0634 32.9605 16.2034 33.8405 15.1234 33.8405C14.6034 33.8405 13.9634 33.6605 13.4034 33.1805Z&quot; fill=&quot;#88619F&quot; fill-opacity=&quot;0.468&quot; /&gt;
&lt;path d=&quot;M22.2556 24.3005H25.1356V32.1205C25.1356 34.6405 26.4156 36.2405 28.9156 36.2405C30.1556 36.2405 30.8556 36.0205 31.8956 35.7005L31.2356 33.5405C30.6156 33.7805 30.1356 33.8605 29.6756 33.8605C28.8556 33.8605 28.0756 33.4605 28.0756 32.2405V21.9805H22.2556V24.3005Z&quot; fill=&quot;#88619F&quot; fill-opacity=&quot;0.468&quot; /&gt;
&lt;path d=&quot;M43.5078 26.0805H40.5678V32.6005C39.8878 33.4805 39.3678 33.7405 38.6278 33.7405C37.5278 33.7405 37.1878 33.1405 37.1878 31.8205V26.0805H34.2478V32.2005C34.2478 34.7005 35.2078 36.2405 37.4678 36.2405C38.8878 36.2405 39.9278 35.5805 40.8078 34.5805H40.8878L41.1078 36.0005H43.5078V26.0805Z&quot; fill=&quot;#88619F&quot; fill-opacity=&quot;0.468&quot; /&gt;
&lt;path d=&quot;M47.32 36.0005H50.26V30.8405C51.1 29.0605 52.38 28.4205 53.6 28.4205C54.34 28.4205 54.74 28.5205 55.36 28.7005L55.96 26.2405C55.38 25.9805 54.92 25.8405 54.04 25.8405C52.46 25.8405 51 26.6205 50.02 28.2405H49.96L49.72 26.0805H47.32V36.0005Z&quot; fill=&quot;#88619F&quot; fill-opacity=&quot;0.468&quot; /&gt;
&lt;path d=&quot;M59.3122 36.0005H62.2522V30.8405C63.0922 29.0605 64.3722 28.4205 65.5922 28.4205C66.3322 28.4205 66.7322 28.5205 67.3522 28.7005L67.9522 26.2405C67.3722 25.9805 66.9122 25.8405 66.0322 25.8405C64.4522 25.8405 62.9922 26.6205 62.0122 28.2405H61.9522L61.7122 26.0805H59.3122V36.0005Z&quot; fill=&quot;#88619F&quot; fill-opacity=&quot;0.468&quot; /&gt;
&lt;path d=&quot;M70.0844 31.0405C70.0844 34.3205 72.5044 36.2405 75.5844 36.2405C76.9044 36.2405 78.3844 35.8005 79.5044 35.0805L78.5444 33.3205C77.6644 33.7605 76.8844 34.0005 75.9844 34.0005C74.5244 34.0005 73.3044 33.3805 73.1044 31.9005H79.7844C79.8244 31.6605 79.9044 31.1205 79.9044 30.6005C79.9044 27.9005 78.3044 25.8405 75.2444 25.8405C72.6044 25.8405 70.0844 27.8005 70.0844 31.0405ZM73.0644 29.9605C73.3244 28.6805 74.2444 28.0805 75.3044 28.0805C76.6444 28.0805 77.2444 28.8405 77.2444 29.9605H73.0644Z&quot; fill=&quot;#88619F&quot; fill-opacity=&quot;0.468&quot; /&gt;
&lt;path d=&quot;M81.9166 31.0405C81.9166 34.2805 83.5766 36.2405 86.0966 36.2405C87.0966 36.2405 88.1166 35.7005 88.8566 34.9805H88.9166L89.1366 36.0005H91.5366V21.9805H88.5966V25.3605L88.6966 26.9005C87.9966 26.2605 87.2966 25.8405 86.1566 25.8405C83.9966 25.8405 81.9166 27.8005 81.9166 31.0405ZM84.9366 31.0005C84.9366 29.1205 85.8566 28.2405 86.9366 28.2405C87.5166 28.2405 88.0566 28.4205 88.5966 28.9005V32.9205C88.0766 33.5805 87.5166 33.8405 86.8566 33.8405C85.6366 33.8405 84.9366 32.9605 84.9366 31.0005Z&quot; fill=&quot;#88619F&quot; fill-opacity=&quot;0.468&quot; /&gt;
&lt;/svg&gt;

    &lt;span class=&quot;post-jumper-title&quot;&gt;Classes&lt;/span&gt;
  &lt;/a&gt;
  &lt;a href=&quot;#network-requests-with-get-or-ajax&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;svg width=&quot;77&quot; height=&quot;48&quot; viewBox=&quot;0 0 77 48&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&lt;rect x=&quot;50.5&quot; y=&quot;27.4961&quot; width=&quot;10&quot; height=&quot;26&quot; rx=&quot;0.5&quot; transform=&quot;rotate(-90 50.5 27.4961)&quot; fill=&quot;#E1D9E7&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;rect x=&quot;0.5&quot; y=&quot;43.4961&quot; width=&quot;42&quot; height=&quot;32&quot; rx=&quot;0.5&quot; transform=&quot;rotate(-90 0.5 43.4961)&quot; fill=&quot;#E1D9E7&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;rect x=&quot;3.5&quot; y=&quot;27.4883&quot; width=&quot;10&quot; height=&quot;26&quot; rx=&quot;0.5&quot; transform=&quot;rotate(-90 3.5 27.4883)&quot; fill=&quot;#F8F8F9&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M21.7778 11.7202C28.0385 6.81061 34.5115 4.65116 40.5617 4.18422C46.612 3.71729 51.732 5.53534 55.8793 9.08837&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M59.6891 12.6072L53.1061 11.5957L58.1129 6.13616L59.6891 12.6072Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M60.1672 34.7834C53.5233 39.1605 46.8945 40.7793 40.8263 40.7462C34.7581 40.7131 29.8053 38.4795 25.9648 34.5968&quot; stroke=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M22.458 30.7745L28.9353 32.3248L23.4957 37.3534L22.458 30.7745Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;/svg&gt;

    &lt;span class=&quot;post-jumper-title&quot;&gt;.ajax()&lt;/span&gt;
  &lt;/a&gt;
  &lt;a href=&quot;#creating-elements&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;svg width=&quot;52&quot; height=&quot;59&quot; viewBox=&quot;0 0 52 59&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&lt;path d=&quot;M13 19C13 18.4477 13.4477 18 14 18H37C37.5523 18 38 18.4477 38 19V42C38 42.5523 37.5523 43 37 43H14C13.4477 43 13 42.5523 13 42V19Z&quot; fill=&quot;#E1D9E7&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M37 19H14V42H37V19ZM14 18C13.4477 18 13 18.4477 13 19V42C13 42.5523 13.4477 43 14 43H37C37.5523 43 38 42.5523 38 42V19C38 18.4477 37.5523 18 37 18H14Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M51.3884 14.841L43.0519 19.654L42.5519 18.788L50.8884 13.975L51.3884 14.841Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M8.94817 39.3451L0.611694 44.1581L0.111694 43.2921L8.44817 38.479L8.94817 39.3451Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M38.0328 50.3397L35.845 46.5504L36.711 46.0504L38.8988 49.8397L38.0328 50.3397Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M13.9674 8.65755L16.1551 12.4469L15.2891 12.9469L13.1014 9.15755L13.9674 8.65755Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M38.0318 8.65712L35.844 12.4464L34.978 11.9464L37.1657 8.15712L38.0318 8.65712Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M13.9664 50.3411L16.1542 46.5518L17.0202 47.0518L14.8325 50.8411L13.9664 50.3411Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M51.3875 44.1577L43.051 39.3446L43.551 38.4786L51.8875 43.2916L51.3875 44.1577Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M8.94723 19.6554L0.610755 14.8423L1.11076 13.9763L9.44723 18.7893L8.94723 19.6554Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M26 0.183594V9.80973H25V0.183594L26 0.183594Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M26 49.19V58.8161H25V49.19H26Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M26 0.183594V9.80973H25V0.183594L26 0.183594Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M26 49.19V58.8161H25V49.19H26Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M50.0653 29.4989H45.6898V28.4989H50.0653V29.4989Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M1.93465 29.4989H6.31016V30.4989H1.93465V29.4989Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;/svg&gt;

    &lt;span class=&quot;post-jumper-title&quot;&gt;Creating elements&lt;/span&gt;
  &lt;/a&gt;
  &lt;a href=&quot;#updating-the-dom&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;svg width=&quot;63&quot; height=&quot;40&quot; viewBox=&quot;0 0 63 40&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&lt;path d=&quot;M8 11C7.44771 11 7 10.5523 7 10L7 7C7 6.44772 7.44772 6 8 6L56 6C56.5523 6 57 6.44772 57 7L57 10C57 10.5523 56.5523 11 56 11L8 11Z&quot; fill=&quot;#E1D9E7&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M8 7L8 10L56 10L56 7L8 7ZM7 10C7 10.5523 7.44771 11 8 11L56 11C56.5523 11 57 10.5523 57 10L57 7C57 6.44772 56.5523 6 56 6L8 6C7.44772 6 7 6.44772 7 7L7 10Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M8 40C7.44771 40 7 39.5523 7 39L7 36C7 35.4477 7.44772 35 8 35L56 35C56.5523 35 57 35.4477 57 36L57 39C57 39.5523 56.5523 40 56 40L8 40Z&quot; fill=&quot;#E1D9E7&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M8 36L8 39L56 39L56 36L8 36ZM7 39C7 39.5523 7.44771 40 8 40L56 40C56.5523 40 57 39.5523 57 39L57 36C57 35.4477 56.5523 35 56 35L8 35C7.44772 35 7 35.4477 7 36L7 39Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M0.999999 5C0.447714 5 -1.95703e-08 4.55228 -4.37114e-08 4L-1.74845e-07 1C-1.98987e-07 0.447717 0.447715 2.36462e-06 1 2.34047e-06L49 2.42328e-07C49.5523 2.18187e-07 50 0.447715 50 1L50 4C50 4.55228 49.5523 5 49 5L0.999999 5Z&quot; fill=&quot;#E1D9E7&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M1 1L0.999999 4L49 4L49 1L1 1ZM-4.37114e-08 4C-1.95703e-08 4.55228 0.447714 5 0.999999 5L49 5C49.5523 5 50 4.55228 50 4L50 1C50 0.447715 49.5523 2.18187e-07 49 2.42328e-07L1 2.34047e-06C0.447715 2.36462e-06 -1.98987e-07 0.447717 -1.74845e-07 1L-4.37114e-08 4Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M14 18C13.4477 18 13 17.5523 13 17L13 14C13 13.4477 13.4477 13 14 13L62 13C62.5523 13 63 13.4477 63 14L63 17C63 17.5523 62.5523 18 62 18L14 18Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M14 14L14 17L62 17L62 14L14 14ZM13 17C13 17.5523 13.4477 18 14 18L62 18C62.5523 18 63 17.5523 63 17L63 14C63 13.4477 62.5523 13 62 13L14 13C13.4477 13 13 13.4477 13 14L13 17Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M14 25C13.4477 25 13 24.5523 13 24L13 21C13 20.4477 13.4477 20 14 20L62 20C62.5523 20 63 20.4477 63 21L63 24C63 24.5523 62.5523 25 62 25L14 25Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M14 21L14 24L62 24L62 21L14 21ZM13 24C13 24.5523 13.4477 25 14 25L62 25C62.5523 25 63 24.5523 63 24L63 21C63 20.4477 62.5523 20 62 20L14 20C13.4477 20 13 20.4477 13 21L13 24Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path d=&quot;M14 32C13.4477 32 13 31.5523 13 31L13 28C13 27.4477 13.4477 27 14 27L62 27C62.5523 27 63 27.4477 63 28L63 31C63 31.5523 62.5523 32 62 32L14 32Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M14 28L14 31L62 31L62 28L14 28ZM13 31C13 31.5523 13.4477 32 14 32L62 32C62.5523 32 63 31.5523 63 31L63 28C63 27.4477 62.5523 27 62 27L14 27C13.4477 27 13 27.4477 13 28L13 31Z&quot; fill=&quot;#88619F&quot; /&gt;
&lt;/svg&gt;

    &lt;span class=&quot;post-jumper-title&quot;&gt;HTML &amp;amp; text&lt;/span&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;h2 id=&quot;selecting-elements&quot;&gt;Selecting elements&lt;/h2&gt;

&lt;p&gt;Selecting one or several DOM elements to do something with is one of the most basic elements of jQuery. The equivalent to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$()&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jQuery()&lt;/code&gt; in JavaScript is &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;querySelector()&lt;/code&gt;&lt;/a&gt; or &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;querySelectorAll()&lt;/code&gt;&lt;/a&gt;, which, just like with jQuery, you can call with a CSS selector.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// jQuery, select all instances of .box&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Instead, select the first instance of .box&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// …or select all instances of .box  &lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelectorAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;running-a-function-on-all-elements-in-a-selection&quot;&gt;Running a function on all elements in a selection&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;querySelectorAll()&lt;/code&gt; returns a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/NodeList&quot;&gt;NodeList&lt;/a&gt; containing all of the elements matching the query. Whereas you can run a function with jQuery on the entire selection of elements simply by calling the method on the jQuery object, however, you’ll have to iterate over the NodeList of elements using &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NodeList.forEach()&lt;/code&gt;&lt;/a&gt; in vanilla JavaScript:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// with jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Hide all instances of .box&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Without jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Iterate over the nodelist of elements to hide all instances of .box&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelectorAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;display&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;none&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;finding-one-element-within-another&quot;&gt;Finding one element within another&lt;/h3&gt;

&lt;p&gt;A common jQuery pattern is to select an element within another element using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.find()&lt;/code&gt;. You can achieve the same effect, scoping the selection to an element’s children, by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;querySelector&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;querySelectorAll&lt;/code&gt; on an element:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// With jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Select the first instance of .box within .container&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;container&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Later...&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Without jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Select the first instance of .box within .container&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;container&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Later...&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;traversing-the-tree-with-parent-next-and-prev&quot;&gt;Traversing the tree with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parent()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next()&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prev()&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;If you wish to traverse the DOM to select a subling or a parent element relative to another element, you can access them through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nextElementSibling&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;previousElementSibling&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parentElement&lt;/code&gt; on that element:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// with jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Return the next, previous, and parent element of .box&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Without jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Return the next, previous, and parent element of .box&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;nextElementSibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;previousElementSibling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parentElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;working-with-events&quot;&gt;Working with events&lt;/h2&gt;

&lt;p&gt;There’s a myriad of ways to listen to events in jQuery, but whether you’re using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.on()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.bind()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.live&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.click()&lt;/code&gt;, you’ll make do with the JavaScript equivalent &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.addEventListener&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// With jQuery&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.button&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* handle click event */&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.button&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mouseenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  &lt;span class=&quot;cm&quot;&gt;/* handle click event */&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;keyup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  &lt;span class=&quot;cm&quot;&gt;/* handle key up event */&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Without jQuery&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.button&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.button&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;mouseenter&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;keyup&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;event-listening-for-dynamically-added-elements&quot;&gt;Event listening for dynamically added elements&lt;/h3&gt;

&lt;p&gt;jQuery’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.on()&lt;/code&gt; method enables you to work with “live” event handlers, where you listen to events on objects that get dynamically added to the DOM. To accomplish something similar without jQuery you can attach the event handler on an element as you add it to the DOM:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// With jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Handle click events .search-result elements, &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// even when they're added to the DOM programmatically&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.search-container&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.search-result&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;handleClick&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Without jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Create and add an element to the DOM&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchElement&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.search-container&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;searchElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Add an event listener to the element&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;searchElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;handleClick&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;triggering-and-creating-events&quot;&gt;Triggering and creating events&lt;/h3&gt;

&lt;p&gt;The equivalent to manually triggering events with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;trigger()&lt;/code&gt; can be achieved by calling &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dispatchEvent()&lt;/code&gt;&lt;/a&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dispatchEvent()&lt;/code&gt; method can be invoked on any element, and takes an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Event&lt;/code&gt; as the first argument:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// With jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Trigger myEvent on document and .box&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;myEvent&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;myEvent&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Without jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Create and dispatch myEvent&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dispatchEvent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;myEvent&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dispatchEvent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;myEvent&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;styling-elements&quot;&gt;Styling elements&lt;/h2&gt;

&lt;p&gt;If you’re calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.css()&lt;/code&gt; on an element to change its inline CSS with jQuery, you’d use &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.style&lt;/code&gt;&lt;/a&gt; in JavaScript and assign values to its different properties to achieve the same effect:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// With jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Select .box and change text color to #000&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#000&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Without jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Select the first .box and change its text color to #000&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#000&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With jQuery, you can pass an object with key-value pairs to style many properties at once. In JavaScript you can set the values one at a time, or set the entire style string:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// With jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Pass multiple styles&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;css&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#000&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;red&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Without jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Set color to #000 and background to red&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#000&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;backgroundColor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;red&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Set all styles at once (and override any existing styles)&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cssText&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;color: #000; background-color: red&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;hide-and-show&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hide()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;show()&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.hide()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.show()&lt;/code&gt; convenience methods are equivalent to accessing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.style&lt;/code&gt; property and setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;display&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;none&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;block&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// With jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Hide and show and element&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;show&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Without jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Hide and show an element by changing &quot;display&quot; to block and none&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;display&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;none&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;display&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;document-ready&quot;&gt;Document ready&lt;/h2&gt;

&lt;p&gt;If you need to wait for the DOM to fully load before e.g. attaching events to objects in the DOM, you’d typically use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$(document).ready()&lt;/code&gt; or the common short-hand &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$()&lt;/code&gt; in jQuery. We can easily construct a similar function to replace it with by listening to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DOMContentLoaded&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// With jQuery&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ready&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
  &lt;span class=&quot;cm&quot;&gt;/* Do things after DOM has fully loaded */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Without jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Define a convenience method and use it&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ready&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;readyState&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;loading&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;DOMContentLoaded&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;ready&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
  &lt;span class=&quot;cm&quot;&gt;/* Do things after DOM has fully loaded */&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;working-with-classes&quot;&gt;Working with classes&lt;/h2&gt;

&lt;p&gt;You can easily access and work with classes through the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Element/classList&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;classList&lt;/code&gt;&lt;/a&gt; property to toggle, replace, add, and remove classes:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// With jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Add, remove, and the toggle the &quot;focus&quot; class&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;removeClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toggleClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Without jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Add, remove, and the toggle the &quot;focus&quot; class&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;classList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;classList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;classList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toggle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you want to remove or add multiple classes you can just pass multiple arguments to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.add()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.remove()&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Add &quot;focus&quot; and &quot;highlighted&quot; classes, and then remove them&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;classList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;highlighted&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;classList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;highlighted&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you’re toggling two classes that are mutually exclusive, you can access the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;classList&lt;/code&gt; property and call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.replace()&lt;/code&gt; to replace one class with another:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Remove the &quot;focus&quot; class and add &quot;blurred&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;classList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;blurred&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;checking-if-an-element-has-a-class&quot;&gt;Checking if an element has a class&lt;/h3&gt;

&lt;p&gt;If you only want to run a function depending on if an element has a certain class, you can replace jQuery’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.hasClass()&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.classList.contains()&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// With jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Check if .box has a class of &quot;focus&quot;, and do something&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hasClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Do something...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Without jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Check if .box has a class of &quot;focus&quot;, and do something&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;classList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Do something...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;network-requests-with-get-or-ajax&quot;&gt;Network requests with .get() or .ajax()&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fetch()&lt;/code&gt;&lt;/a&gt; lets you create network requests in a similar fashion to jQuery’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ajax()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get()&lt;/code&gt; methods. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fetch()&lt;/code&gt; takes a URL as an argument, and returns a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise&quot;&gt;Promise&lt;/a&gt; that you can use to handle the response:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// With jQuery&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;data.json&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Handle error&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Without jQuery&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;data.json&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Handle data&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Handle error&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;creating-elements&quot;&gt;Creating elements&lt;/h2&gt;

&lt;p&gt;If you want to dynamically create an element in JavaScript to add to the DOM you can call &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;createElement()&lt;/code&gt;&lt;/a&gt; on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;document&lt;/code&gt; and pass it a tag name to indicate what element you want to create:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Create a div &amp;amp; span&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;div/&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;span/&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Create a div and a span&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;span&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you want to add some content to those elements, you can simply set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;textContent&lt;/code&gt; property, or create a text node with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Document/createTextNode&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;createTextNode&lt;/code&gt;&lt;/a&gt; and append it to the element:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;textContent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// or create a textNode and append it&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createTextNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;updating-the-dom&quot;&gt;Updating the DOM&lt;/h2&gt;

&lt;p&gt;If you’re looking to change the text of an element or to add new elements to the DOM chances are that you’ve come across &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;innerHTML()&lt;/code&gt;, but using it may expose you to cross-site scripting (XSS) attacks. &lt;a href=&quot;https://gomakethings.com/preventing-cross-site-scripting-attacks-when-using-innerhtml-in-vanilla-javascript/&quot;&gt;Although you can work around it and sanitize the HTML&lt;/a&gt;, there are some safer alternatives.&lt;/p&gt;

&lt;p&gt;If you’re only looking to read or update the text of an element, you can use the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;textContent&lt;/code&gt;&lt;/a&gt; property of an object to return the current text, or update it:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// With jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Update the text of a .button&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.button&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;New text&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Read the text of a .button&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.button&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Returns &quot;New text&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Without jQuery&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Update the text of a .button&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.button&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;textContent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;New text&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Read the text of a .button&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.button&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;textContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Returns &quot;New text&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you’re constructing a new element, you can then add that element to another element by using the method on the parent &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appendChild()&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Create div element and append it to .container&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;div/&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Create a div and append it to .container&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Put together, here’s how to create a div, update its text and class, and add it to the DOM:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Create a div&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Update its class&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;classList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Set its text&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;textContent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Text inside box&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Append the element to .container&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;in-summary&quot;&gt;In summary&lt;/h2&gt;

&lt;p&gt;This is by no means a comprehensive guide to any of the native JavaScript methods utilized here, but I hope it’s been helpful a guide if you’re looking to move away from jQuery. In summary, here are the methods that we’ve covered:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Selecting elements with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;querySelector&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;querySelectorAll&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Listening for events with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addEventListener&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Updating CSS and styles through &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;style&lt;/code&gt;&lt;/a&gt; property&lt;/li&gt;
  &lt;li&gt;Working with classes through the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Element/classList&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;classList&lt;/code&gt;&lt;/a&gt; property&lt;/li&gt;
  &lt;li&gt;AJAX requests with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fetch&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Triggering events with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dispatchEvent&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Creating elements with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;createElement&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Updating text through the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;textContent&lt;/code&gt;&lt;/a&gt; property&lt;/li&gt;
  &lt;li&gt;Adding elements to the DOM with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appendChild&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
				<pubDate>Sun, 21 Jul 2019 07:50:00 +0000</pubDate>
				<link>https://tobiasahlin.com/blog/move-from-jquery-to-vanilla-javascript/</link>
				<guid isPermaLink="true">https://tobiasahlin.com/blog/move-from-jquery-to-vanilla-javascript/</guid>
			</item>
		
			<item>
				<title>Breaking to a new row with flexbox</title>
				<description>&lt;div class=&quot;blog-banner&quot;&gt;
  &lt;div class=&quot;blog-banner-content&quot;&gt;
      &lt;div class=&quot;flexbox-break-banner-logo&quot;&gt;
        &lt;div class=&quot;flexbox-break-box flexbox-break-box-1&quot; style=&quot;transform: translateX(-60px) scaleY(0.36) scaleX(0.12);&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;flexbox-break-box flexbox-break-box-2&quot; style=&quot;transform: translateX(-60px) scaleY(0.36) scaleX(0.12);&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;flexbox-break-box flexbox-break-box-3&quot; style=&quot;transform: translateX(-60px) scaleY(0.36) scaleX(0.12);&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;flexbox-break-box flexbox-break-box-4&quot; style=&quot;transform: translateX(-60px) scaleY(0.36) scaleX(0.12);&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;flexbox-break-box flexbox-break-box-5&quot; style=&quot;transform: translateX(-60px) scaleY(0.36) scaleX(0.12);&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;flexbox-break-box flexbox-break-box-6&quot; style=&quot;transform: translateX(-60px) scaleY(0.36) scaleX(0.12);&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;flexbox-break-box flexbox-break-box-7&quot; style=&quot;transform: translateX(-60px) scaleY(0.36) scaleX(0.12);&quot;&gt;&lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.flexbox-break-banner-logo {
  margin-top: 20px;
  width: 100px;
  height: 30px;
  display: inline-block;
  position: relative;
}

.flexbox-break-box {
  background-color: #fff;
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: 50% 0;
}
&lt;/style&gt;

&lt;script&gt;
var postMasonryBoxTimeline = anime.timeline({ loop: true });
postMasonryBoxTimeline
  .add({ /* just one line */ 
    targets: '.flexbox-break-box',
    translateX: function(el, i) { return -60+i*20 },
    scaleY: 0.36,
    scaleX: 0.12,
    delay: function(el, i) { return i*70 },
    easing: &quot;easeOutExpo&quot;,
    duration: 600
  })
  .add({
    targets: '.flexbox-break-box',
    translateY: function(el, i) { 
      if (i &gt; 3) return 20;
      if (i == 3) return 0;
      return -20;
    },
    translateX: function(el, i) {
      if (i == 0 || i == 4) return -27;
      if (i == 1 || i == 3 || i == 5) return 0;
      return 27;
    },
    scaleY: 0.36,
    scaleX: function(el, i) { return i == 3 ? 0.72 : 0.17 },
    easing: &quot;easeOutExpo&quot;,
    delay: function(el, i) { return 800 + i*20 },
    duration: 700
  })
  .add({
    targets: '.flexbox-break-box',
    translateY: 0,
    translateX: 0,
    scaleY: 0.36,
    scaleX: 0.12,
    easing: &quot;easeInExpo&quot;,
    delay: function(el, i) { return 800 + i*70 },
    duration: 600
  })
  .add({
    targets: '.flexbox-break-box',
    translateX: -60,
    scaleY: 0.36,
    scaleX: 0.12,
    duration: 800
  });
app.animations.track(postMasonryBoxTimeline, document.querySelector(&quot;.flexbox-break-banner-logo&quot;));
&lt;/script&gt;

&lt;!--more--&gt;

&lt;p&gt;Here’s the challenge: if you want to create a flexbox layout with several rows of items, how do you control which item ends up in which row? Presume you want to create a layout that looks something like this, with three stacked items and alternating full-width items:&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-rows&quot;&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-break flex-rows-break-invisible&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-break flex-rows-break-invisible&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-break flex-rows-break-invisible&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;A common way of controlling the positioning and size of flex items is to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-basis&lt;/code&gt;; if we set the fourth item to have a width of 100% it’ll be positioned on its own row. But what if we don’t want to or can’t set the width of individual items, do we really need to? Or is there a way of just telling flexbox to line break at certain points?&lt;/p&gt;

&lt;p&gt;There’s no property that we can set on a flex item to make it break to a new row, but we can insert a collapsed row (you can think of it as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;br&amp;gt;&lt;/code&gt;) between two flex items two achieve something similar. In a gist:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;/* Inserting this collapsed row between two flex items will make 
 * the flex item that comes after it break to a new row */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.break&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-basis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;break&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- break --&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s walk through some scenarios when you might want to use this, and look at some interesting layout techniques that it enables us to use.&lt;/p&gt;

&lt;p&gt;Note that all of the code examples below requires and assumes that you have a flex container with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;display: flex&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-wrap: wrap&lt;/code&gt; and that the flex items are added to that container:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-wrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  ...
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;inserting-a-line-breaking-flex-item&quot;&gt;Inserting a line-breaking flex item&lt;/h2&gt;

&lt;p&gt;Using an element to break to a new flex row comes with an interesting effect: we can skip specifying the width of any item in our flex layout and rely completely on the line breaks to define the flow of our grid.&lt;/p&gt;

&lt;p&gt;Let’s start with a simple example. Say that we have two items shown side by side (these are set to grow with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow: 1&lt;/code&gt;, and they have no defined &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-basis&lt;/code&gt;):&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-rows&quot;&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;We can insert a line breaking element between the items to make them both take up 100% of the available space:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;break&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- break to a new row --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This produces a layout with two vertically stacked full-width items (I’ve added a border to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.break&lt;/code&gt; element to illustrate its position and behavior):&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-rows&quot;&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-break&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;How does this work? Since we’ve said that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.break&lt;/code&gt; should take up 100% of the width of the container (because we set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-basis: 100%&lt;/code&gt;), the breaking flex item needs to sit on its own row to accomplish that. It can’t share a row with the first item so it will break to a new row, which will leave the first item alone on one row. The first item will then grow to fill the remaining space (since we set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow: 1&lt;/code&gt;). The same logic applies to the second item.&lt;/p&gt;

&lt;p&gt;We can use this technique to compose the layout at the top of the post by breaking before and after every fourth item:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;break&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- break --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;break&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- break --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will produce the layout at the top of the blog post. Essentially an item won’t break to a new row unless we insert the line-breaking element:&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-rows&quot;&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-break&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-break&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Again, we didn’t need to specify the width on any of those items. The same technique will work for columns if we have a flex container with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-direction: column&lt;/code&gt;, and set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt; (rather than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;height&lt;/code&gt;) to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; for our breaking element:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;/* Use a collapsed column to break to a new column */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.break-column&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-basis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-rows flex-rows-columns&quot;&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-break&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-break&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This approach of using line breaking elements to define a layout definitely adds some bloat and noise to our HTML, but it can be a powerful tool when used in the right way. &lt;a href=&quot;/blog/masonry-with-css/&quot;&gt;We can, for example, use it to build a masonry layout with CSS only&lt;/a&gt;, and position the breaks dynamically with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; property. We can also break to a new row without having to modify the width of any content item, and we can rely solely on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow&lt;/code&gt; to distribute space in a grid layout.&lt;/p&gt;

&lt;p&gt;Suppose that we’re looking to create this layout:&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-rows&quot;&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child flex-rows-child-wide&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;And assume that we want to do so by setting different values of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow&lt;/code&gt; to distribute the space (rather than using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-basis&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt;, which you’d have to recalculate as soon as you added or removed items):&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;flex-grow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item-wide&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;flex-grow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item-wide&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If we then want to add another row of items below that row:&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-rows&quot;&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child flex-rows-child-wide&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-break flex-rows-break-invisible&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;We wouldn’t be able to do so without resorting to setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-basis&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt; on at least some of the items (or creating a nested flexbox layout with one flex item for every row). If all of the items just have different values of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow&lt;/code&gt; nothing would make them break to a new row, they’d all just squeeze in on one row together:&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-rows&quot;&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child flex-rows-child-wide&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Cozy, but not what we’re after. If we insert a breaking element, however, we can construct this layout by distributing all space with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;flex-grow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item-wide&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;flex-grow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item-wide&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;break&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- break --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Yielding the desired layout, with all sizes defined proportionally through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-rows&quot;&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child flex-rows-child-wide&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-break&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;And if there’s a scenario when we need five items in the first row we don’t have to change any of the CSS to make that work, we can just add those items before the line break:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item-wide&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;break&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- break --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-rows&quot;&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child flex-rows-child-wide&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-break flex-rows-break-invisible&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;flex-rows-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;All that you need to add to your CSS to use line-breaking elements are these two classes (the only difference between the two classes is that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt; (and not &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;height&lt;/code&gt;) needs to be set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; for the element to collapse when used in a column layout):&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;/* Inserting a collapsed row between two flex items will make 
 * the flex item that comes after it break to a new row */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.break&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-basis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;/* Use a collapsed column to break to a new column */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.break-column&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-basis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You could certainly achieve the same effect or similar effects by nesting flexboxes and having one flex item for every row, and in many cases just utilizing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-basis&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt;, or the content within the flex items is probably the preferred way of controlling the flow of items in a flexbox layout. But inserting line-breaking flex items is approachable and easy to grok, it works, and the technique comes with some unique characteristics that may come in handy.&lt;/p&gt;

&lt;style&gt;

.flex-rows {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  padding: 20px 20px 5px 20px;
}

.flex-rows-columns {
  flex-direction: column;
  height: 300px;
}

.flex-rows-child {
  border-radius: 3px;
  background-color: #A2CBFA;
  border: 1px solid #4390E1;
  box-sizing: border-box;
  box-shadow: 0 2px 2px rgba(0,90,250,0.05),
    0 4px 4px rgba(0,90,250,0.05),
    0 8px 8px rgba(0,90,250,0.05),
    0 16px 16px rgba(0,90,250,0.05);
    height: 60px;
  flex-grow: 1;
  margin-bottom: 2%;
}

.flex-rows-child-wide { flex-grow: 3; }

.flex-rows-child + .flex-rows-child { margin-left: 2%; }

.flex-rows-columns .flex-rows-child {
  height: auto;
  width: 30%;
  margin-left: 0;
}

.flex-rows-break {
  flex-basis: 100%;
  height: 0;
  margin: 0;
  border: 1px solid #ddd;
  margin-bottom: 2%;
}

.flex-rows-break-invisible { 
  border: 0; 
  margin: 0;
}

.flex-rows-columns .flex-rows-break {
  width: 0;
  height: auto;
}
&lt;/style&gt;

</description>
				<pubDate>Mon, 29 Apr 2019 07:50:00 +0000</pubDate>
				<link>https://tobiasahlin.com/blog/flexbox-break-to-new-row/</link>
				<guid isPermaLink="true">https://tobiasahlin.com/blog/flexbox-break-to-new-row/</guid>
			</item>
		
			<item>
				<title>CSS masonry with flexbox, :nth-child(), and order</title>
				<description>&lt;div class=&quot;blog-banner&quot;&gt;
  &lt;div class=&quot;blog-banner-content&quot;&gt;
      &lt;div class=&quot;masonry-banner-logo&quot;&gt;
        &lt;div class=&quot;masonry-box masonry-box-1&quot; style=&quot;transform: scaleY(0.1) scaleX(0.15);&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;masonry-box masonry-box-2&quot; style=&quot;transform: scaleY(0.1) scaleX(0.15);&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;masonry-box masonry-box-3&quot; style=&quot;transform: scaleY(0.1) scaleX(0.15);&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;masonry-box masonry-box-4&quot; style=&quot;transform: scaleY(0.1) scaleX(0.15);&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;masonry-box masonry-box-5&quot; style=&quot;transform: scaleY(0.1) scaleX(0.15);&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;masonry-box masonry-box-6&quot; style=&quot;transform: scaleY(0.1) scaleX(0.15);&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;masonry-box masonry-box-7&quot; style=&quot;transform: scaleY(0.1) scaleX(0.15);&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;masonry-box masonry-box-8&quot; style=&quot;transform: scaleY(0.1) scaleX(0.15);&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;masonry-box masonry-box-9&quot; style=&quot;transform: scaleY(0.1) scaleX(0.15);&quot;&gt;&lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.masonry-banner-logo {
  width: 100px;
  height: 70px;
  display: inline-block;
  position: relative;
}

.masonry-box {
  background-color: #fff;
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: 50% 0;
}
&lt;/style&gt;

&lt;script&gt;
var postMasonryBoxTimeline = anime.timeline({ loop: true });
postMasonryBoxTimeline
  .add({ 
    targets: '.masonry-box',
    translateX: function(el, i) { 
      if (i &lt; 3) return &quot;-23px&quot;;
      if (i &gt; 5) return &quot;23px&quot;;
      return 0;
    },
    opacity: [0,1],
    translateY: function(el, i) { 
      var amount = (i%3)*26;
      return amount + &quot;px&quot;;
    },
    scaleY: function(el, i) {
      if (i == 0) return 0.2;
      if (i == 1) return 0.1;
      if (i == 2) return 0.15;
      if (i == 3) return 0.11;
      if (i == 4) return 0.19;
      if (i == 5) return 0.12;
      if (i == 6) return 0.14;
      if (i == 7) return 0.1;
      if (i == 8) return 0.16;
    },
    scaleX: [0, 0.15],
    duration: 600,
    delay: function(el, i) {
      return 400 + i*70;
    },
    easing: &quot;easeOutExpo&quot;
  }).add({ 
    targets: '.masonry-box',
    translateX: function(el, i) { 
      if (i &lt; 3) return &quot;-23px&quot;;
      if (i &gt; 5) return &quot;23px&quot;;
      return 0;
    },
    translateY: function(el, i) { 
      if (i == 0) return 0  + &quot;px&quot;;
      if (i == 1) return 24 + &quot;px&quot;;
      if (i == 2) return 38 + &quot;px&quot;;
      if (i == 3) return 0  + &quot;px&quot;;
      if (i == 4) return 15 + &quot;px&quot;;
      if (i == 5) return 38 + &quot;px&quot;;
      if (i == 6) return 0  + &quot;px&quot;;
      if (i == 7) return 18 + &quot;px&quot;;
      if (i == 8) return 32 + &quot;px&quot;;
    },
    scaleY: function(el, i) {
      if (i == 0) return 0.2;
      if (i == 1) return 0.1;
      if (i == 2) return 0.15;
      if (i == 3) return 0.11;
      if (i == 4) return 0.19;
      if (i == 5) return 0.12;
      if (i == 6) return 0.14;
      if (i == 7) return 0.1;
      if (i == 8) return 0.16;
    },
    scaleX: 0.15,
    duration: 500,
    delay: 700,
    easing: &quot;easeOutExpo&quot;
  }).add({ 
    targets: '.masonry-box',
    opacity: 0,
    translateY: &quot;+=10px&quot;,
    duration: 700,
    translateX: function(el, i) { 
      if (i &lt; 3) return &quot;-23px&quot;;
      if (i &gt; 5) return &quot;23px&quot;;
      return 0;
    },
    scaleY: function(el, i) {
      if (i == 0) return 0.2;
      if (i == 1) return 0.1;
      if (i == 2) return 0.18;
      if (i == 3) return 0.11;
      if (i == 4) return 0.19;
      if (i == 5) return 0.12;
      if (i == 6) return 0.14;
      if (i == 7) return 0.1;
      if (i == 8) return 0.14;
    },
    scaleX: 0.15,
    delay: function(el, i) { return 1800 + i*40 },
    easing: &quot;easeInExpo&quot;
  });
app.animations.track(postMasonryBoxTimeline, document.querySelector(&quot;.masonry-banner-logo&quot;));
&lt;/script&gt;

&lt;!--more--&gt;

&lt;p&gt;On the surface it seems fairly easy to create a masonry layout with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox&quot;&gt;flexbox&lt;/a&gt;; all you need to do is set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-flow&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;column wrap&lt;/code&gt; and voilà, you have a masonry layout. Sort of. The problem with this approach is that it produces a grid with a seemingly shuffled and obscure order. Items will be (unbeknownst to the user) rendered from top to bottom and someone parsing the grid from left to right will read the boxes in a somewhat arbitrary order, for example 1, 3, 6, 2, 4, 7, 8, 5, and so on so forth.&lt;/p&gt;

&lt;p&gt;Flexbox has no easy way of rendering items with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;column&lt;/code&gt; layout while using a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;row&lt;/code&gt; order, but we can build a masonry layout with CSS only—no JavaScript needed—by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:nth-child()&lt;/code&gt; and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; property. In a gist, here’s the trick to create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;row&lt;/code&gt; order while using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-direction: column&lt;/code&gt;, given that you’re rendering three columns:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;/* Render items as columns */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-flow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;column&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;/* Re-order items into rows */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;/* Force new columns */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;::before&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;::after&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-basis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will create a masonry layout with items rendered as columns but ordered as rows (the gray vertical lines represent the pseudo elements that &lt;a href=&quot;/blog/flexbox-break-to-new-row/&quot;&gt;force line breaks&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-masonry&quot;&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-1&quot;&gt;1&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-2&quot;&gt;2&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-3&quot;&gt;3&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-4&quot;&gt;4&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-5&quot;&gt;5&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-6&quot;&gt;6&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-7&quot;&gt;7&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-8&quot;&gt;8&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-9&quot;&gt;9&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-10&quot;&gt;10&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Let’s break down the implementation (or &lt;a href=&quot;#the-solution&quot;&gt;jump to the solution&lt;/a&gt;, or &lt;a href=&quot;https://codepen.io/collection/XPjvPP/&quot;&gt;see the codepen collection&lt;/a&gt;).&lt;/p&gt;

&lt;h2 id=&quot;pick-your-poison-a-shuffled-order-or-weird-gaps&quot;&gt;Pick your poison: a shuffled order, or weird gaps&lt;/h2&gt;

&lt;p&gt;Flexbox is not really built for masonry—if you set a fixed height on a flex container (so that items can wrap when they overflow) and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-flow&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;column wrap&lt;/code&gt;, you’ll achieve something like this:&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-columns&quot;&gt;
    &lt;div class=&quot;flex-child flex-column-child flex-column-child-1&quot;&gt;1&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-column-child flex-column-child-2&quot;&gt;2&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-column-child flex-column-child-3&quot;&gt;3&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-column-child flex-column-child-4&quot;&gt;4&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-column-child flex-column-child-5&quot;&gt;5&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-column-child flex-column-child-6&quot;&gt;6&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-column-child flex-column-child-7&quot;&gt;7&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-column-child flex-column-child-8&quot;&gt;8&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-column-child flex-column-child-9&quot;&gt;9&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-column-child flex-column-child-10&quot;&gt;10&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Items are rendered in columns from top to bottom, producing an arbitrary order when read from left to right. This is of course the expected outcome and desirable in many scenarios, but not when we’re trying to create a masonry layout, and it becomes increasingly disorienting as a page grows taller.&lt;/p&gt;

&lt;p&gt;If we instead change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-direction&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;row&lt;/code&gt; and have elements of varying heights we’ll achieve the correct order but with weird and unexpected gaps all over our grid:&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-rows&quot;&gt;
    &lt;div class=&quot;flex-child flex-row-child flex-column-child-1&quot;&gt;1&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-row-child flex-column-child-2&quot;&gt;2&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-row-child flex-column-child-3&quot;&gt;3&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-row-child flex-column-child-4&quot;&gt;4&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-row-child flex-column-child-5&quot;&gt;5&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-row-child flex-column-child-6&quot;&gt;6&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-row-child flex-column-child-7&quot;&gt;7&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-row-child flex-column-child-8&quot;&gt;8&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-row-child flex-column-child-9&quot;&gt;9&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-row-child flex-column-child-10&quot;&gt;10&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;So it seems impossible to get the best of both worlds: items rendered as columns but ordered as rows. You might decide to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-direction: column&lt;/code&gt; and just move around the elements in your HTML to achieve the right &lt;em&gt;visual&lt;/em&gt; order, but this can be cumbersome, it’s unnecessarily complex, and it will mess up the tab order of the elements.&lt;/p&gt;

&lt;h2 id=&quot;re-ordering-elements-with-order-and-nth-child&quot;&gt;Re-ordering elements with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nth-child()&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; property affects the order of items contained in a CSS flexbox or grid, and we can use it to re-order items for our soon-to-be masonry layout. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; property is pretty straight-forward to use: if you have two elements and one has &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order: 1&lt;/code&gt; and the other one has &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order: 2&lt;/code&gt; the element with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order: 1&lt;/code&gt; will be rendered before the other element, independent of their HTML source code order.&lt;/p&gt;

&lt;p&gt;The CSS masonry solution depends on a detail of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; specification: what happens if two or more elements have the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; value? Which comes first? Flexbox falls back on the source code order: the element that appears first in the source code will be rendered before other elements with the same order value. This fact gives us the possibility to easily re-group items in our grid so that we can change the ordering from columns to rows, while still rendering those rows as columns, using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nth-child()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Look at the table below. To achieve a sensible order using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-direction: row&lt;/code&gt; we’d just have to render elements in the default order: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1, 2, 3, 4, 5, 6&lt;/code&gt; , etc.&lt;/p&gt;

&lt;table class=&quot;article-table masonry-table-1&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt; &lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Column 1&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Column 2&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Column 3&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Row 1&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;1&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Row 2&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;4&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;5&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;6&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Row 3&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;7&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;8&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;9&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Row 4&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;10&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;11&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;12&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;If we want to achieve the &lt;em&gt;same&lt;/em&gt; order while using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-direction: column&lt;/code&gt; we need to change the order of the elements to match the order of each column in the table (rather than each row):&lt;/p&gt;

&lt;table class=&quot;article-table masonry-table-2&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt; &lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Column 1&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Column 2&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Column 3&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Row 1&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Row 2&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;5&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;6&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Row 3&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;strong&gt;7&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;8&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;9&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Row 4&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;11&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;12&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;style&gt;
.masonry-table-2 tr td:nth-child(2), .masonry-table tr th:nth-child(2) {
  background-color: #A2CBFA;
  border-radius: 2px;
}
&lt;/style&gt;

&lt;p&gt;I.e. the first elements in our flexbox layout have to be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1, 4, 7, 10&lt;/code&gt;. These items will fill up the first column, followed by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2, 5, 8, 11&lt;/code&gt; for the 2nd column and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3, 6, 9, 12&lt;/code&gt; for the 3rd and last column. This is where the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nth-child()&lt;/code&gt; selector comes in. We can use it to select every third element (3n), starting with the first element (3n+1), and set all those elements to have the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; value:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This selector sets &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order: 1&lt;/code&gt; for element &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1, 4, 7, 10&lt;/code&gt; in our container, i.e. the entire first column. In other words we’re using a combination of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nth-child()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; to re-order items depending on their original order. To create the 2nd and 3rd column we just change the offset:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here we’re producing three sets: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1, 4, 7, 10&lt;/code&gt; (3n+1) with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order: 1&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2, 5, 8, 11&lt;/code&gt; (3n+2) with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order: 2&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3, 6, 9, 12&lt;/code&gt; (3n) with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order: 3&lt;/code&gt;. All together the order becomes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1, 4, 7, 10, 2, 5, 8, 11, 3, 6, 9, 12&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we make sure to render each of those groups as one column (and no more), it’ll create the illusion that the items have returned to their original order when you read from left to right. If we visually parse the grid as rows the first row will contain the first element from every group (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1, 2, 3&lt;/code&gt;), the second row will contain the second element from every group (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4, 5, 6&lt;/code&gt;), and so on so forth. With this technique we can create a masonry layout with items rendered as columns but ordered as rows.&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-masonry&quot;&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-1&quot;&gt;1&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-2&quot;&gt;2&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-3&quot;&gt;3&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-4&quot;&gt;4&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-5&quot;&gt;5&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-6&quot;&gt;6&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-7&quot;&gt;7&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-8&quot;&gt;8&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-9&quot;&gt;9&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonry-child-10&quot;&gt;10&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;How is the tab order affected by shuffling around elements like this? Luckily, not at all. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; only changes the visual representation of objects, not the tab order, so tabbing through the grid will work as intended.&lt;/p&gt;

&lt;h2 id=&quot;preventing-columns-from-merging&quot;&gt;Preventing columns from merging&lt;/h2&gt;

&lt;p&gt;If you have many items in a masonry layout this technique will fairly certainly break down at some point. We’re counting on that every “group” that we’ve created will be rendered as exactly one column but in reality items can have different heights and columns can easily start to merge. The first column could be longer than the other two, for example, which could make the third column start at the end of the second column:&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-masonryfail&quot;&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-1&quot;&gt;1&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-2&quot;&gt;2&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-child-highlight flex-masonryfail-child-3&quot;&gt;3&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-4&quot;&gt;4&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-5&quot;&gt;5&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-6&quot;&gt;6&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-7&quot;&gt;7&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-8&quot;&gt;8&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-9&quot;&gt;9&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-10&quot;&gt;10&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The highlighted box here (3) has to be rendered at the start of the third column or the ordering algorithm will break, but if there’s space for another element at the end of the 2nd column it will naturally be rendered there.&lt;/p&gt;

&lt;p&gt;We can fix this wrapping issue by forcing columns to restart at certain points. There’s no easy way of saying “this element should line break” with flexbox, but &lt;a href=&quot;/blog/flexbox-break-to-new-row/&quot;&gt;we can achieve this effect by adding invisible elements that take up 100% of the container’s height&lt;/a&gt;. As they require 100% of the parent’s height to be rendered they won’t fit in a column together with any other element, so they’ll essentially force line breaks by creating  collapsed columns.&lt;/p&gt;

&lt;p&gt;We have to insert these line break elements into our grid and array of elements, so what we’re looking for is to create this sequence of elements: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1, 4, 7, 10, &amp;lt;break&amp;gt;, 2, 5, 8, 11, &amp;lt;break&amp;gt;, 3, 6, 9, 12&lt;/code&gt;. We can use pseudo-elements on the container to add these, and we can set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt; on both of them. Adding a pseudo-element with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:before&lt;/code&gt; will make it the first child of the container and adding a pseudo-element with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:after&lt;/code&gt; will make it the last child of the container, so if we set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order: 2&lt;/code&gt; on both of them they will become the first and the last element of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order: 2&lt;/code&gt; “group” (as they appear before and after the other elements): &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:before, 2, 5, 8, 11, :after&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;/* Force new columns */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;::before&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;::after&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-basis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’ve highlighted the pseudo-elements below to show their effect. Notice that despite that box 3 would fit in the 2nd column it’s rendered as the first element in the last column:&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-masonryfail flex-masonryfail-fixed&quot;&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-1&quot;&gt;1&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-2&quot;&gt;2&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-3&quot;&gt;3&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-4&quot;&gt;4&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-5&quot;&gt;5&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-6&quot;&gt;6&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-7&quot;&gt;7&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-8&quot;&gt;8&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-9&quot;&gt;9&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child flex-masonryfail-child-10&quot;&gt;10&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h2 id=&quot;the-solution&quot;&gt;The solution&lt;/h2&gt;

&lt;p&gt;As a final step, you need to make sure that your flex container has a set height that makes it taller than your tallest column (so that all columns will fit). Put together, this will produce a CSS masonry layout with three columns (&lt;a href=&quot;https://codepen.io/tobiasahlin/pen/JVmLRa&quot;&gt;also available as a codepen&lt;/a&gt;):&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-flow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;column&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;align-content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;space-between&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;/* Your container needs a fixed height, and it 
   * needs to be taller than your tallest column. */&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;600px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* Optional */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;/* Re-order items into 3 rows */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;/* Force new columns */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;::before&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;::after&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-basis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Your HTML should look like this, with one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;div /&amp;gt;&lt;/code&gt; for every item in your grid:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  ...
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;working-with-more-than-three-columns&quot;&gt;Working with more than three columns&lt;/h2&gt;

&lt;p&gt;To create a masonry layout with more than three columns we need to do a few things: adapt our sorting algorithm, update the width of the items, and insert line break elements manually (instead of using pseudo-elements). For quick access to the final result I’ve compiled &lt;a href=&quot;https://codepen.io/collection/XPjvPP/&quot;&gt;a list of codepens showcasing flexbox masonry with 3, 4, 5 and 6 columns&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since we’re limited to creating just two pseudo-elements with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:before&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:after&lt;/code&gt; we need to resort to manually adding break elements into our container (you need one less break element than the number of columns in your layout). You can just append them to the end of your container, they’ll be sorted into their respective columns:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  ...
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item break&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item break&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;span&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item break&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’re inserting column breaks as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;span&lt;/code&gt;s in order to sort them independently from the content items. We need a way to “restart” the counting once we reach the break elements, or an uneven number of content items could make the first break element start after the 3rd column, for example. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:nth-of-type&lt;/code&gt; selector targets elements of different types independently, so we can decouple the order of the content items and the column breaks like so:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-of-type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-of-type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-of-type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-of-type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The break elements, like previously, take up the full height of the container:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;/* Force new columns */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.break&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-basis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will create a masonry layout with four columns (&lt;a href=&quot;https://codepen.io/tobiasahlin/pen/OGBvqW&quot;&gt;view codepen&lt;/a&gt;):&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex-masonry flex-masonry-4columns&quot;&gt;
    &lt;div class=&quot;flex-child flex-masonry-child-4columns flex-masonry-child-1&quot;&gt;1&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child-4columns flex-masonry-child-2&quot;&gt;2&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child-4columns flex-masonry-child-3&quot;&gt;3&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child-4columns flex-masonry-child-4&quot;&gt;4&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child-4columns flex-masonry-child-5&quot;&gt;5&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child-4columns flex-masonry-child-6&quot;&gt;6&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child-4columns flex-masonry-child-7&quot;&gt;7&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child-4columns flex-masonry-child-8&quot;&gt;8&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child-4columns flex-masonry-child-9&quot;&gt;9&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child-4columns flex-masonry-child-10&quot;&gt;10&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child-4columns flex-masonry-child-11&quot;&gt;11&lt;/div&gt;
    &lt;div class=&quot;flex-child flex-masonry-child-4columns flex-masonry-child-12&quot;&gt;12&lt;/div&gt;
    &lt;span class=&quot;flex-masonry-child-4columns flex-masonry-break&quot;&gt;&lt;/span&gt;
    &lt;span class=&quot;flex-masonry-child-4columns flex-masonry-break&quot;&gt;&lt;/span&gt;
    &lt;span class=&quot;flex-masonry-child-4columns flex-masonry-break&quot;&gt;&lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Here’s the full solution for a CSS masonry layout with four columns:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-flow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;column&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;align-content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;space-between&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;/* Your container needs a fixed height, and it 
   * needs to be taller than your tallest column. */&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;600px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;24%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* Optional */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;/* Re-order items into 4 rows */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-of-type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-of-type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-of-type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-of-type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;/* Force new columns */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.break&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-basis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This CSS-only way of creating a masonry (or mosaic) layout is surely not as robust, flexible, and foolproof as a JavaScript implementation (like &lt;a href=&quot;https://masonry.desandro.com/&quot;&gt;Masonry&lt;/a&gt;) but if you don’t want to rely on a third-party library just to create a masonry layout I hope that these layouts tricks can come in handy.&lt;/p&gt;

&lt;p&gt;For help with more common CSS flexbox patterns, &lt;a href=&quot;/blog/common-flexbox-patterns/&quot;&gt;I’ve compiled a list of flexbox examples that you can copy and paste into your projects&lt;/a&gt; and &lt;a href=&quot;/blog/flexbox-break-to-new-row/&quot;&gt;written in-depth about the line-breaking flexbox item technique&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://twitter.com/gilbitron&quot;&gt;Gilbert Pellegrom&lt;/a&gt; has created &lt;a href=&quot;https://flexmasonry.now.sh&quot;&gt;FlexMasonry&lt;/a&gt;, a lightweight JavaScript masonry library inspired by the technique outlined in this article&lt;/li&gt;
  &lt;li&gt;October, 2020: the CSS Working Group has now published a &lt;a href=&quot;https://drafts.csswg.org/css-grid-3/&quot;&gt;draft specification for masonry layouts&lt;/a&gt;, as part of CSS grid&lt;/li&gt;
  &lt;li&gt;CSS masonry &lt;a href=&quot;https://css-houdini.rocks/masonry/&quot;&gt;can also be implemented&lt;/a&gt; with &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Houdini&quot;&gt;Houdini&lt;/a&gt; (requires flag)&lt;/li&gt;
&lt;/ul&gt;

&lt;style&gt;
.flex-masonry,
.flex-masonryfail {
  background-color: #f7f7f7;
  border-radius: 3px;
  padding: 20px;
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  height: 580px;
}

.flex-columns {
  background-color: #f7f7f7;
  border-radius: 3px;
  padding: 20px;
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  height: 530px;
}

.flex-rows {
  padding: 20px;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
}

.flex-child {
  border-radius: 3px;
  background-color: #A2CBFA;
  border: 1px solid #4390E1;
  box-shadow: 0 2px 2px rgba(0,90,250,0.05),
    0 4px 4px rgba(0,90,250,0.05),
    0 8px 8px rgba(0,90,250,0.05),
    0 16px 16px rgba(0,90,250,0.05);
  width: 32%;
  margin-bottom: 2%; /* (100-32*3)/2 */
  padding: 10px;
  box-sizing: border-box;
  text-align: center;
  color: white;
}

.flex-child-highlight {
  background-color: #cc4a8b;
  border-color: #8a2155;
}

.flex-column-child-1 { height: 200px; }
.flex-column-child-2 { height: 150px; }
.flex-column-child-3 { height: 125px; }
.flex-column-child-4 { height: 150px; }
.flex-column-child-5 { height: 100px; }
.flex-column-child-6 { height: 125px; }
.flex-column-child-7 { height: 100px; }
.flex-column-child-8 { height: 125px; }
.flex-column-child-9 { height: 100px; }
.flex-column-child-10 { height: 100px; }

.flex-masonry-child-1 { height: 200px; }
.flex-masonry-child-2 { height: 205px; }
.flex-masonry-child-3 { height: 175px; }
.flex-masonry-child-4 { height: 100px; }
.flex-masonry-child-5 { height: 100px; }
.flex-masonry-child-6 { height: 155px; }
.flex-masonry-child-7 { height: 100px; }
.flex-masonry-child-8 { height: 175px; }
.flex-masonry-child-9 { height: 150px; }
.flex-masonry-child-10 { height: 100px; }
.flex-masonry-child-11 { height: 150px; }
.flex-masonry-child-12 { height: 100px; }

.flex-masonryfail-child-1 { height: 200px; }
.flex-masonryfail-child-2 { height: 205px; }
.flex-masonryfail-child-3 { height: 75px; }
.flex-masonryfail-child-4 { height: 100px; }
.flex-masonryfail-child-5 { height: 100px; }
.flex-masonryfail-child-6 { height: 155px; }
.flex-masonryfail-child-7 { height: 100px; }
.flex-masonryfail-child-8 { height: 75px; }
.flex-masonryfail-child-9 { height: 150px; }
.flex-masonryfail-child-10 { height: 100px; }

.flex-masonry-child:nth-child(3n+1) { order: 1; }
.flex-masonry-child:nth-child(3n+2) { order: 2; }
.flex-masonry-child:nth-child(3n) { order: 3; }

.flex-masonry::before,
.flex-masonry::after {
  content: &quot;&quot;;
  flex-basis: 100%;
  width: 0;
  order: 2;
  border: 1px solid #ddd;
}

.flex-masonryfail-fixed::before,
.flex-masonryfail-fixed::after {
  content: &quot;&quot;;
  flex-basis: 100%;
  width: 0;
  order: 2;
  border: 1px solid #8a2155;
}

/* Four columns */
.flex-masonry-4columns {
  height: 520px;
}

.flex-masonry-4columns::after,
.flex-masonry-4columns::before {
  content: none;
}

.flex-masonry-child-4columns {
  width: 24%;
}

.flex-masonry-child-4columns:nth-of-type(4n+1) { order: 1; }
.flex-masonry-child-4columns:nth-of-type(4n+2) { order: 2; }
.flex-masonry-child-4columns:nth-of-type(4n+3) { order: 3; }
.flex-masonry-child-4columns:nth-of-type(4n)   { order: 4; }

.flex-masonry-break {
  flex-basis: 100%;
  width: 0;
  border: 1px solid #ddd;
  margin: 0;
}
&lt;/style&gt;

</description>
				<pubDate>Mon, 15 Apr 2019 11:12:00 +0000</pubDate>
				<link>https://tobiasahlin.com/blog/masonry-with-css/</link>
				<guid isPermaLink="true">https://tobiasahlin.com/blog/masonry-with-css/</guid>
			</item>
		
			<item>
				<title>Common CSS Flexbox Layout Patterns with Example Code</title>
				<description>&lt;div class=&quot;blog-banner&quot;&gt;
  &lt;div class=&quot;blog-banner-content&quot;&gt;
      &lt;div class=&quot;flexbox-banner-logo&quot;&gt;
        &lt;div class=&quot;flexbox-box flexbox-box-1&quot; style=&quot;transform: translateY(-23px) scaleY(0.15)&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;flexbox-box flexbox-box-2&quot; style=&quot;transform: translateY(0) scaleY(0.15); &quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;flexbox-box flexbox-box-3&quot; style=&quot;transform: translateY(23px) scaleY(0.15);&quot;&gt;&lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.flexbox-banner-logo {
  width: 100px;
  height: 100px;
  display: inline-block;
  position: relative;
}

.flexbox-box {
  background-color: #fff;
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}
&lt;/style&gt;

&lt;script&gt;
var postFlexBoxTimeline = anime.timeline({ loop: true });
postFlexBoxTimeline
  .add({ /* hamburger */ 
    targets: '.flexbox-box',
    translateY: function(el, i) { return -23+(i*23) },
    scaleY: 0.15,
    duration: 500
  })
  .add({ /* collapsed hamburger */
    targets: '.flexbox-box',
    translateY: 0,
    scaleY: 0.15,
    duration: 900,
    easing: &quot;easeInOutExpo&quot;,
    delay: 800
  })
  .add({ /* one vertical line */
    targets: '.flexbox-box',
    scaleY: 1,
    scaleX: 0.15,
    easing: &quot;easeOutExpo&quot;,
    duration: 400
  })
  .add({ /* flipped hamburger */
    targets: '.flexbox-box',
    translateX: function(el, i) { return -30+(i*30) },
    scaleY: 0.9,
    scaleX: 0.15,
    easing: &quot;easeOutExpo&quot;,
    duration: 700
  })
  .add({ /* Wide flipped hamburger */
    targets: '.flexbox-box',
    translateX: function(el, i) { return -50+(i*50) },
    scaleY: 0.9,
    scaleX: function(el, i) { return i == 1 ? 0.7 : 0.15 },
    easing: &quot;easeOutExpo&quot;,
    duration: 500,
    delay: 800
  })
  .add({ /* Wide collapsed flipped hamburger */
    targets: '.flexbox-box',
    translateX: function(el, i) { return -50+(i*50) },
    scaleY: 0.15,
    scaleX: function(el, i) { return i == 1 ? 0.7 : 0.15 },
    easing: &quot;easeOutExpo&quot;,
    duration: 500,
    delay: 800
  })
  .add({
    targets: '.flexbox-box',
    translateX: function(el, i) { 
      if (i == 0) return &quot;-23px&quot;;
      if (i == 1) return 0;
      return &quot;23px&quot;;
    },
    translateY: function(el, i) { return i == 1 ? &quot;-12px&quot; : &quot;12px&quot; },
    scaleY: 0.15,
    scaleX: function(el, i) { return i == 1 ? 0.84 : 0.38 },
    easing: &quot;easeOutExpo&quot;,
    duration: 500,
    delay: 800
  })
  .add({ /* hamburger */ 
    targets: '.flexbox-box',
    translateY: function(el, i) { 
      if (i == 0) return 0;
      if (i == 1) return &quot;-23px&quot;;
      return &quot;23px&quot;;
    },
    translateX: 0,
    scaleY: 0.15,
    scaleX: 1,
    easing: &quot;easeOutExpo&quot;,
    duration: 500,
    delay: 800
  });
app.animations.track(postFlexBoxTimeline, document.querySelector(&quot;.flexbox-banner-logo&quot;));
&lt;/script&gt;

&lt;!--more--&gt;

&lt;p&gt;In theory, it’s pretty straightforward to use &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox&quot;&gt;flexbox&lt;/a&gt; (Flexible Box Module) to build complex layouts, but I’ve often found myself adding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;display: flex&lt;/code&gt; to an element and then promptly spending an eternity trying to figure out how to make anything behave like I expect it to. If you’re anything like me: here’s a list of 10 example flexbox layouts with CSS that you can copy and paste to get started with your own layouts. We’ll walk through these basic layout patterns (click to jump to an example):&lt;/p&gt;

&lt;div class=&quot;post-jumper post-jumper-5&quot;&gt;
  &lt;a href=&quot;#stretch-all-fixed-spacing&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;div class=&quot;icon-flex flex1&quot;&gt;
      &lt;div class=&quot;icon-child flex1-child&quot; style=&quot;height: 40px&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex1-child&quot; style=&quot;height: 40px&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex1-child&quot; style=&quot;height: 40px&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex1-child&quot; style=&quot;height: 40px&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;span class=&quot;post-jumper-title&quot;&gt;Stretch all&lt;/span&gt;
  &lt;/a&gt;  
  &lt;a href=&quot;#stretch-middle-fixed-spacing&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;div class=&quot;icon-flex flex2&quot;&gt;
      &lt;div class=&quot;icon-child flex2-child&quot; style=&quot;width: 20px; height: 40px&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex2-child flex2-child-center&quot; style=&quot;height: 40px&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex2-child&quot; style=&quot;width: 20px; height: 40px&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;span class=&quot;post-jumper-title&quot;&gt;Stretch middle&lt;/span&gt;
  &lt;/a&gt;
  &lt;a href=&quot;#alternating-grid&quot; class=&quot;post-jumper-item&quot;&gt;
   &lt;div class=&quot;icon-flex flex3&quot;&gt;
      &lt;div style=&quot;height: 15px;&quot; class=&quot;icon-child flex3-child&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;height: 15px;&quot; class=&quot;icon-child flex3-child&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;height: 15px;&quot; class=&quot;icon-child flex3-child&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;height: 15px;&quot; class=&quot;icon-child flex3-child&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;height: 15px;&quot; class=&quot;icon-child flex3-child&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;span class=&quot;post-jumper-title&quot;&gt;Alternating grid&lt;/span&gt;
  &lt;/a&gt;
  &lt;a href=&quot;#3x3-grid&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;div class=&quot;icon-flex flex4&quot;&gt;
      &lt;div style=&quot;height: 15px&quot; class=&quot;icon-child flex4-child&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;height: 15px&quot; class=&quot;icon-child flex4-child&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;height: 15px&quot; class=&quot;icon-child flex4-child&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;height: 15px&quot; class=&quot;icon-child flex4-child&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;height: 15px&quot; class=&quot;icon-child flex4-child&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;height: 15px&quot; class=&quot;icon-child flex4-child&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;height: 15px&quot; class=&quot;icon-child flex4-child&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;height: 15px&quot; class=&quot;icon-child flex4-child&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;height: 15px&quot; class=&quot;icon-child flex4-child&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;span class=&quot;post-jumper-title&quot;&gt;3x3 grid&lt;/span&gt;
  &lt;/a&gt;
  &lt;a href=&quot;#3x3-grid-constrained-proportions-11&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;div style=&quot;width: 52px&quot; class=&quot;icon-flex flex5&quot;&gt;
      &lt;div class=&quot;icon-child flex5-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex5-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex5-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex5-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex5-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex5-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex5-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex5-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex5-child&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;span class=&quot;post-jumper-title&quot;&gt;3x3 (1:1)&lt;/span&gt;
  &lt;/a&gt;
  &lt;a href=&quot;#3x3-grid-constrained-proportions-169&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;div class=&quot;icon-flex flex6&quot;&gt;
      &lt;div class=&quot;icon-child flex6-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex6-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex6-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex6-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex6-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex6-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex6-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex6-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex6-child&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;span class=&quot;post-jumper-title&quot;&gt;3x3 (16:9)&lt;/span&gt;
  &lt;/a&gt;
  &lt;a href=&quot;#graph-vertical-bars&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;div class=&quot;icon-flex flex7&quot;&gt;
      &lt;div class=&quot;icon-child flex7-child flex7-child-1&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex7-child flex7-child-2&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex7-child flex7-child-3&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex7-child flex7-child-4&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex7-child flex7-child-5&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;span class=&quot;post-jumper-title&quot;&gt;Vertical bars&lt;/span&gt;
  &lt;/a&gt;
  &lt;a href=&quot;#graph-horizontal-bars&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;div class=&quot;icon-flex flex8&quot;&gt;
      &lt;div class=&quot;icon-child flex8-child flex8-child-1&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex8-child flex8-child-2&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex8-child flex8-child-3&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex8-child flex8-child-4&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex8-child flex8-child-5&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;span class=&quot;post-jumper-title&quot;&gt;Horizontal bars&lt;/span&gt;
  &lt;/a&gt;
  &lt;a href=&quot;#vertical-stack-centered&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;div class=&quot;icon-flex flex9&quot;&gt;
      &lt;div class=&quot;icon-child flex9-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex9-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex9-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex9-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex9-child&quot;&gt;&lt;/div&gt;
     &lt;/div&gt;
    &lt;span class=&quot;post-jumper-title&quot;&gt;Vertical stack&lt;/span&gt;
  &lt;/a&gt;
  &lt;a href=&quot;#masonry-or-mosaic&quot; class=&quot;post-jumper-item&quot;&gt;
    &lt;div class=&quot;icon-flex flex10 icon-flex10&quot;&gt;
      &lt;div class=&quot;icon-child flex10-child icon-flex10-child flex10-child-1 icon-flex10-child-1&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex10-child icon-flex10-child flex10-child-2 icon-flex10-child-2&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex10-child icon-flex10-child flex10-child-3 icon-flex10-child-3&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex10-child icon-flex10-child flex10-child-4 icon-flex10-child-4&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex10-child icon-flex10-child flex10-child-5 icon-flex10-child-5&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex10-child icon-flex10-child flex10-child-6 icon-flex10-child-6&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex10-child icon-flex10-child flex10-child-7 icon-flex10-child-7&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex10-child icon-flex10-child flex10-child-8 icon-flex10-child-8&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex10-child icon-flex10-child flex10-child-9 icon-flex10-child-9&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;icon-child flex10-child icon-flex10-child flex10-child-10 icon-flex10-child-10&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;span class=&quot;post-jumper-title&quot;&gt;Masonry&lt;/span&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;Every example assumes that your HTML contains an element with a class of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;container&lt;/code&gt; which then contains several children that all have a class of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;item&lt;/code&gt; (the number of children varies per example):&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;item&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  ...
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;style&gt;
.icon-flex {
  max-height: 56px;
  max-width: 70px;
  width: 100%;
  margin: 0 auto;
}

.icon-child {
  border-radius: 2px;
  background-color: #A2CBFA;
  border: 1px solid #4390E1;
  box-sizing: border-box;
}

.flex {
  background-color: #f7f7f7;
  border-radius: 3px;
  padding: 20px;
}

.child {
  border-radius: 3px;
  background-color: #A2CBFA;
  border: 1px solid #4390E1;
  box-sizing: border-box;
  box-shadow: 0 2px 2px rgba(0,90,250,0.05),
    0 4px 4px rgba(0,90,250,0.05),
    0 8px 8px rgba(0,90,250,0.05),
    0 16px 16px rgba(0,90,250,0.05);
}
&lt;/style&gt;

&lt;h2 id=&quot;stretch-all-fixed-spacing&quot;&gt;Stretch all, fixed spacing&lt;/h2&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex flex1&quot;&gt;
      &lt;div class=&quot;child flex1-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;child flex1-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;child flex1-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;child flex1-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;child flex1-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;style&gt;
.flex1 {
  display: flex;
}

.flex1-child {
  flex-grow: 1;
  height: 100px;
}

.flex1-child + .flex1-child {
  margin-left: 2%;
}
&lt;/style&gt;

&lt;p&gt;The most basic flexbox pattern: getting a few boxes to stretch and fill the full width of their parent element. All you need to do is to set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;display: flex&lt;/code&gt; on the container, and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow&lt;/code&gt; value above &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; on the children:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-grow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We use a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+&lt;/code&gt; selector to only add gaps between pairs of items (essentially just skipping the left margin for the first item in the list).&lt;/p&gt;

&lt;p&gt;Increasing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow&lt;/code&gt; will increase &lt;em&gt;the amount of space&lt;/em&gt; that an element is allowed to stretch to compared to any other element. If we set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow&lt;/code&gt;to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt; on the middle element here, we would basically divide up the available space into 6 chunks (1 chunk for each item plus 1 extra for the middle item, 1+1+2+1+1). The middle item gets two chunks (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow: 2&lt;/code&gt;) worth of space, and all other elements get one chunk (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow: 1&lt;/code&gt;).&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex flex1&quot;&gt;
      &lt;div class=&quot;child flex1-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;child flex1-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;child flex1-child&quot; style=&quot;flex-grow: 2&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;child flex1-child&quot;&gt;&lt;/div&gt;
      &lt;div class=&quot;child flex1-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h2 id=&quot;stretch-middle-fixed-spacing&quot;&gt;Stretch middle, fixed spacing&lt;/h2&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex flex2&quot;&gt;
    &lt;div class=&quot;child flex2-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex2-child flex2-child-center&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex2-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
  /* Example 2 */
.flex2 {
  display: flex;
}

.flex2-child {
  height: 100px;
  width: 100px;
}

.flex2-child-center {
  flex-grow: 1;
}

.flex2-child + .flex2-child {
  margin-left: 2%;
}
&lt;/style&gt;

&lt;p&gt;A common app and web pattern is to create a top bar where we want to stretch only the middle element, but keep the right most and left most elements fixed. If we just want one element to stretch, we can set a fixed width (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;100px&lt;/code&gt;) on an element that should stay static, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow: 1&lt;/code&gt; on the element that should stretch:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* A fixed width as the default */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item-center&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
  &lt;span class=&quot;nl&quot;&gt;flex-grow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* Set the middle element to grow and stretch */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
  &lt;span class=&quot;nl&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Even if the middle element here has a defined &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;100px&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow&lt;/code&gt; will make it stretch to take up all the available space.&lt;/p&gt;

&lt;h2 id=&quot;alternating-grid&quot;&gt;Alternating grid&lt;/h2&gt;

&lt;p&gt;A layout pattern that I use on my &lt;a href=&quot;/blog/&quot;&gt;blog overview&lt;/a&gt; is to create a grid with some variation: after every row of two equally sized items there’s one item that takes up an entire row:&lt;/p&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex flex3&quot;&gt;
    &lt;div class=&quot;child flex3-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex3-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex3-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex3-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex3-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style type=&quot;text/css&quot;&gt;
  /* Example 3 */
.flex3 {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.flex3-child {
  width: 49%;
  height: 100px;
  margin-bottom: 2%;
}

.flex3-child:nth-child(3n) {
  width: 100%;
}
&lt;/style&gt;

&lt;p&gt;To accomplish this we need to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-wrap: wrap&lt;/code&gt; on the container (or all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;items&lt;/code&gt; would be rendered on a single row)&lt;/li&gt;
  &lt;li&gt;Set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;justify-content: space-between&lt;/code&gt; on the container, to only create space between the elements (and not between the edge of the parent element and items)&lt;/li&gt;
  &lt;li&gt;Set every item’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;49%&lt;/code&gt; (or something similar that is equal to or less than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;50%&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Set every third item’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;100%&lt;/code&gt; so that it fills that entire row. We can target every third item in the list with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nth-child()&lt;/code&gt; selector.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-wrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;justify-content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;space-between&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;48%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you want the first row to be full-width and the two following items to share a row, note that you can’t write &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.item:nth-child(1n) { width: 100% }&lt;/code&gt;—that would target all items. You have to target the first item by selecting every third element, and then stepping back two items: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.item:nth-child(3n-2) { width: 100% }&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;3x3-grid&quot;&gt;3x3 grid&lt;/h2&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex flex4&quot;&gt;
    &lt;div class=&quot;child flex4-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex4-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex4-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex4-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex4-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex4-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex4-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex4-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex4-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;  
&lt;/div&gt;
&lt;style&gt;
.flex4 {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.flex4-child {
  flex: 0 32%;
  height: 100px;
  margin-bottom: 2%;
}
&lt;/style&gt;

&lt;p&gt;We can create a 3x3 grid by setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-grow&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-basis&lt;/code&gt; to the preferred width for all children (here done using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex&lt;/code&gt; short-hand: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex: 0 32%&lt;/code&gt;). The margins between the items are the leftovers from every row, i.e. (100%-32x3)/2=2%. I’ve matched the margin (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;margin-bottom: 2%&lt;/code&gt;) to achieve even spacing between all elements:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-wrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;justify-content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;space-between&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* (100-32*3)/2 */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-basis&lt;/code&gt; to increase or decrease the number of items on each row. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex: 0 24%&lt;/code&gt; would put 4 items on every row, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex: 0 19%&lt;/code&gt; would put 5 items on every row, and so on so forth.&lt;/p&gt;

&lt;h2 id=&quot;3x3-grid-constrained-proportions-11&quot;&gt;3x3 grid, constrained proportions (1:1)&lt;/h2&gt;
&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex flex5&quot;&gt;
    &lt;div class=&quot;child flex5-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex5-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex5-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex5-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex5-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex5-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex5-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex5-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex5-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.flex5 {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.flex5-child {
  width: 32%;
  padding-bottom: 32%;
  margin-bottom: 2%; /* (100-32*3)/2 */
}
&lt;/style&gt;

&lt;p&gt;We can create a grid full of items with constrained proportions by using a somewhat hacky &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;padding&lt;/code&gt; CSS trick. If we use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%&lt;/code&gt; when setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;padding&lt;/code&gt; on an element the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;padding&lt;/code&gt; is set relative to that item’s parent’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.container&lt;/code&gt; in this case. We can use that effect to create a square by setting an item’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;padding-bottom&lt;/code&gt; to the same value (and effectively setting the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;height&lt;/code&gt; of that element through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;padding-bottom&lt;/code&gt;):&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-wrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;justify-content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;space-between&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;padding-bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* Same as width, sets height */&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* (100-32*3)/2 */&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since we’ve created an element that is effectively made up of only padding, and there’s no place left for content, we need to set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;position: relative&lt;/code&gt; on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.item&lt;/code&gt; in this example and add a child element with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;position: absolute&lt;/code&gt;, and use that element to “reset” the canvas and add content.&lt;/p&gt;

&lt;h2 id=&quot;3x3-grid-constrained-proportions-169&quot;&gt;3x3 grid, constrained proportions (16:9)&lt;/h2&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex flex6&quot;&gt;
    &lt;div class=&quot;child flex6-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex6-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex6-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex6-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex6-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex6-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex6-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex6-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex6-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.flex6 {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.flex6-child {
  width: 32%;
  padding-bottom: 18%; /* Proportions between 32 and 18 is 16:9 */
  margin-bottom: 2%; /* (100-32*3)/2 */
}
&lt;/style&gt;

&lt;p&gt;To change the proportions of the items all you need to do is change the proportions of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;padding-bottom&lt;/code&gt; on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.item&lt;/code&gt;. Changing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt; would affect the number of items on each row, so as to not affect the grid structure we can for example change &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;padding-bottom&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;18%&lt;/code&gt; to create 16:9 (equivalent to 32:18) rectangles.&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-wrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;justify-content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;space-between&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;padding-bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;18%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* 32:18, i.e. 16:9 */&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* (100-32*3)/2 */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;graph-vertical-bars&quot;&gt;Graph: vertical bars&lt;/h2&gt;
&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex flex7&quot;&gt;
    &lt;div class=&quot;child flex7-child flex7-child-1&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex7-child flex7-child-2&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex7-child flex7-child-3&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex7-child flex7-child-4&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex7-child flex7-child-5&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.flex7 {
  display: flex;
  height: 300px;
  justify-content: space-between;
  align-items: flex-end;
}

.flex7-child {
  width: 14%;
}

.flex7-child-1 { height: 40%; }
.flex7-child-2 { height: 50%; }
.flex7-child-3 { height: 60%; }
.flex7-child-4 { height: 20%; }
.flex7-child-5 { height: 30%; }
&lt;/style&gt;

&lt;p&gt;If you want to use flexbox to create a simple graph visualization, all you need to do is to set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;align-items&lt;/code&gt; of the container to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-end&lt;/code&gt; and define a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;height&lt;/code&gt; for each bar. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-end&lt;/code&gt; will make sure that the bars are anchored to the bottom of the graph.&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;300px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;justify-content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;space-between&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;align-items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex-end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;14%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item-1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item-2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;50%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item-3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;60%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item-4&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;20%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item-5&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;30%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;graph-horizontal-bars&quot;&gt;Graph: horizontal bars&lt;/h2&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex flex8&quot;&gt;
    &lt;div class=&quot;child flex8-child flex8-child-1&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex8-child flex8-child-2&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex8-child flex8-child-3&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex8-child flex8-child-4&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex8-child flex8-child-5&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.flex8 {
  display: flex;
  height: 300px;
  justify-content: space-between;
  flex-direction: column;
}

.flex8-child {
  height: 14%;
}

.flex8-child-1 { width: 40%; }
.flex8-child-2 { width: 50%; }
.flex8-child-3 { width: 60%; }
.flex8-child-4 { width: 20%; }
.flex8-child-5 { width: 30%; }
&lt;/style&gt;

&lt;p&gt;Using the same technique as for vertical bars, we can simply add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-direction&lt;/code&gt; on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;container&lt;/code&gt; with a value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;column&lt;/code&gt; to create a set of horizontal bars. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-direction&lt;/code&gt; can have a value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;row&lt;/code&gt; (default) or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;column&lt;/code&gt;, where a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;row&lt;/code&gt; runs horizontally (→) and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;column&lt;/code&gt; runs vertically (↓). You can also reverse the direction of both by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;row-reverse&lt;/code&gt; (←) and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;column-reverse&lt;/code&gt; (↑) respectively.&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;300px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;justify-content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;space-between&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-direction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;14%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item-1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item-2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;50%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item-3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;60%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item-4&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;20%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item-5&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;30%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;vertical-stack-centered&quot;&gt;Vertical stack (centered)&lt;/h2&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex flex9&quot;&gt;
    &lt;div class=&quot;child flex9-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex9-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex9-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex9-child&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;child flex9-child&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.flex9 {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.flex9-child {
  width: 40%;
  height: 40px;
  margin-bottom: 2%;
}
&lt;/style&gt;

&lt;p&gt;To create a vertical stack and make the items run from top to bottom all we need to do is to change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-direction&lt;/code&gt; from the default value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;row&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;column&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-direction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;align-items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;masonry-or-mosaic&quot;&gt;Masonry (or mosaic)&lt;/h2&gt;

&lt;div class=&quot;post-content-wrapper&quot;&gt;
  &lt;div class=&quot;flex flex10&quot;&gt;
    &lt;div class=&quot;child flex10-child flex10-child-1&quot;&gt;1&lt;/div&gt;
    &lt;div class=&quot;child flex10-child flex10-child-2&quot;&gt;2&lt;/div&gt;
    &lt;div class=&quot;child flex10-child flex10-child-3&quot;&gt;3&lt;/div&gt;
    &lt;div class=&quot;child flex10-child flex10-child-4&quot;&gt;4&lt;/div&gt;
    &lt;div class=&quot;child flex10-child flex10-child-5&quot;&gt;5&lt;/div&gt;
    &lt;div class=&quot;child flex10-child flex10-child-6&quot;&gt;6&lt;/div&gt;
    &lt;div class=&quot;child flex10-child flex10-child-7&quot;&gt;7&lt;/div&gt;
    &lt;div class=&quot;child flex10-child flex10-child-8&quot;&gt;8&lt;/div&gt;
    &lt;div class=&quot;child flex10-child flex10-child-9&quot;&gt;9&lt;/div&gt;
    &lt;div class=&quot;child flex10-child flex10-child-10&quot;&gt;10&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.flex10 {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  height: 580px;
}

.flex10::before,
.flex10::after {
  content: &quot;&quot;;
  flex-basis: 100%;
  width: 0;
  order: 2;
  border: 1px solid #ddd;
}

.icon-flex10::before,
.icon-flex10::after {
  border: 0;
}

.flex10-child {
  width: 32%;
  margin-bottom: 2%; /* (100-32*3)/2 */
  padding: 10px;
  box-sizing: border-box;
  text-align: center;
  color: white;
}

.flex10-child-1 { height: 200px; }
.flex10-child-2 { height: 250px; }
.flex10-child-3 { height: 225px; }
.flex10-child-4 { height: 100px; }
.flex10-child-5 { height: 100px; }
.flex10-child-6 { height: 125px; }
.flex10-child-7 { height: 100px; }
.flex10-child-8 { height: 75px; }
.flex10-child-9 { height: 100px; }
.flex10-child-10 { height: 100px; }

.flex10-child:nth-child(3n+1) { order: 1; }
.flex10-child:nth-child(3n+2) { order: 2; }
.flex10-child:nth-child(3n) { order: 3; }

/* For icon at the top */
.icon-flex10-child {
  padding: 0;
  border-radius: 1px;
}
.icon-flex10-child-1 { height: 10px; }
.icon-flex10-child-2 { height: 22px; }
.icon-flex10-child-3 { height: 14px; }
.icon-flex10-child-4 { height: 15px; }
.icon-flex10-child-5 { height: 16px; }
.icon-flex10-child-6 { height: 17px; }
.icon-flex10-child-7 { height: 12px; }
.icon-flex10-child-8 { height: 12px; }
.icon-flex10-child-9 { height: 12px; }
.icon-flex10-child-10 { height: 10px; }
&lt;/style&gt;

&lt;p&gt;You’ve probably seen masonry (or mosaic) layouts all over the internet, but it’s likely that they were all powered by &lt;a href=&quot;https://masonry.desandro.com&quot;&gt;Masonry&lt;/a&gt; or a similar JavaScript library. Flexbox might seem like a great candidate to finally create this layout with CSS only, and it’s certainly possible, but it’s surprisingly hacky.&lt;/p&gt;

&lt;p&gt;One of the main challenges of creating a masonry layout with flexbox is that to make an item affect the positioning of an item above and below it we need to change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flex-direction&lt;/code&gt; of the container to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;column&lt;/code&gt;, which makes items run from top to bottom. This creates a layout that looks great, and similar to the masonry effect, but it could be confusing for users; it creates an unexpected ordering of elements. If you read from left to right the elements would seem to be shuffled and appear in a seemingly random order, for example 1, 3, 6, 2, 4, 7, 8, etc.&lt;/p&gt;

&lt;p&gt;Luckily, we can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; property to change in which order elements are rendered. We can combine that property with some clever use of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nth-child()&lt;/code&gt; selector to order items dynamically depending on their original order. If we want to create a masonry layout with three columns we can divide all the items into three “groups”, like so:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;/* Re-order items into rows */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;/* Force new columns */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;::before&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;::after&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-basis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’ve written &lt;a href=&quot;/blog/masonry-with-css/&quot;&gt;another post that explains in detail how this works and why&lt;/a&gt;. This will set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt; for the 1st element, 4th element, 7th element, etc. Elements with the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; value will be ordered on ascending order according to the source code order, or which value was &lt;em&gt;set&lt;/em&gt; first, so in this example we’re producing three sets ordered like so: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1, 4, 7, 10&lt;/code&gt; (3n+1) with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order: 1&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2, 5, 8&lt;/code&gt; (3n+2) with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order: 2&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3, 6, 9&lt;/code&gt; (3n) with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order: 3&lt;/code&gt;. These three groups represent our three columns. Put together the order becomes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1, 4, 7, 10, 2, 5, 8, 3, 6, 9&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we make sure to render each of those groups as one column (no more, no less), it’ll create the illusion that the items have returned to their original order when you read from left to right. If we visually parse the grid as rows, the first row will contain the first element from every group (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1, 2, 3&lt;/code&gt;), the second row will contain the second element from every group (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4, 5, 6&lt;/code&gt;), and so on so forth. We then insert elements between the columns that take up 100% of the parent’s height, &lt;a href=&quot;/blog/flexbox-break-to-new-row/&quot;&gt;which force the columns to line break&lt;/a&gt; and not accidentally merge with adjacent columns. Here’s the full CSS snippet:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-flow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;column&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;align-content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;space-between&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;580px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* (100-32*3)/2 */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;/* Re-order items into rows */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.item&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;:nth-child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;/* Force new columns */&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;::before&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;::after&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;flex-basis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Visually this achieves something that is very close to the masonry effect. How is the tab order affected? Luckily, not at all. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;order&lt;/code&gt; only changes the visual representation of objects, not the tab order, so tabbing through the grid will work as intended.&lt;/p&gt;

&lt;p&gt;If you want to make a masonry layout with more than three columns (or want a better understanding of how this works) I recommend reading &lt;a href=&quot;/blog/masonry-with-css/&quot;&gt;the dedicated post on how to create masonry layouts with CSS&lt;/a&gt;.&lt;/p&gt;
</description>
				<pubDate>Mon, 15 Apr 2019 10:12:00 +0000</pubDate>
				<link>https://tobiasahlin.com/blog/common-flexbox-patterns/</link>
				<guid isPermaLink="true">https://tobiasahlin.com/blog/common-flexbox-patterns/</guid>
			</item>
		
	</channel>
</rss>
