<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://web.dev/</id>
  <title>Bramus on web.dev</title>
  <updated>2026-04-15T23:21:06Z</updated>
  <author>
    <name>Bramus</name>
  </author>
  <link href="https://web.dev/authors/bramus/feed.xml" rel="self"/>
  <link href="https://web.dev/"/>
  <icon>https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/CQMqvg5UkY4weDnJij3b.jpeg?auto=format</icon>
  <logo>https://web.dev/images/shared/rss-banner.png</logo>
  <subtitle>Developer Advocate for CSS, UI, and DevTools at Chrome</subtitle>
  
  
  <entry>
    <title>Trigonometric functions in CSS</title>
    <link href="https://web.dev/css-trig-functions/"/>
    <updated>2023-03-08T00:00:00Z</updated>
    <id>https://web.dev/css-trig-functions/</id>
    <content type="html" mode="escaped">&lt;aside class=&quot;aside flow bg-state-good-bg color-state-good-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 128 128&quot; style=&quot;enable-background:new 0 0 128 128&quot; xml:space=&quot;preserve&quot;&gt;&lt;path d=&quot;M7.5 123.3c2.2 2.4 11.6-1.9 19-5.3C32 115.4 54 106.3 65 101.6c3-1.2 7.3-2.9 10.4-7 2.8-3.6 10-19-4.6-34.7-15-16-30.4-11.5-36.2-7.5A28.5 28.5 0 0 0 27.3 63c-5.2 11.6-12.7 32.9-15.7 41.3-2.3 6.1-6.4 16.5-4.1 19z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M18 86.8s.7 6.5 6.1 14.6c6.3 9.6 15 11.2 15 11.2l-5.8 2.4s-6.5-2-12.7-10.4c-3.8-5.3-5-11.6-5-11.6l2.3-6.2zm-5.6 15.4s1.5 5.6 4.7 9.7c3.8 5 8.6 6.5 8.6 6.5l-4.5 2s-3.3-.8-7-5.5c-2.9-3.5-3.7-7.6-3.7-7.6l1.9-5.1z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 116.4c-.2-.5-.2-1 0-1.4l25.4-53 4.2 16-26.8 38.7c-.7 1-2.3 1-2.8-.2z&quot; style=&quot;opacity:.44&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M41.6 83.2c12 14 25.5 12.2 30 8.6 4.5-3.5 8.1-15.6-3.7-29.3C55.3 48.2 41.3 52.2 38 55.3s-7.4 15.1 3.5 27.9z&quot; style=&quot;fill: var(--color-state-good-bg);&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M82.5 89c-4.3-3.7-6.6-3-9.7-1.8a26 26 0 0 1-18.9 0l2.6-6.2c5 1.7 8.7 1 12-1 4-2.4 9.6-5.6 18.3 1.6 3.6 3 7.3 5.1 10 4.2 2-.7 3-3.6 3.6-6l.2-1.3c.4-3.7 1.2-11.6 7.1-15.7 6.4-4.3 13-4.3 13-4.3l1.2 12c-3-.5-5.2.1-7 1-6.7 3.8-.8 18.2-11.3 23-10.1 4.8-18.4-3.3-21-5.6zM45.4 73.7l-4.3-3.9c8-8.9 5.8-15.4 4.3-20.2A26.4 26.4 0 0 1 44 38.8c-3-3.8-4.4-7.8-4.5-8-1.9-5.7-.5-11.2 2.8-16.4C48.7 4 60.5 4 60.5 4l4 10.5c-3-.1-12.8 0-15.8 4.8-3.8 6-1.3 9.6-1.2 10 .8-1 1.5-1.7 2.2-2.3 4.8-4.2 9-4.8 11.6-4.6a11 11 0 0 1 7.6 4.2c2 2.7 3 6.2 2.3 9.4a11 11 0 0 1-5.8 7.4 16 16 0 0 1-13 1.5v.3l.6 2c1.8 5.4 5 14.1-7.6 26.5zm7.4-37.5c.5.4 1.1.8 1.8 1 2 .8 4.4.6 7-.8 1.5-.9 1.7-1.7 1.7-2 .2-.9 0-2-.7-2.8a2.8 2.8 0 0 0-2-1.2c-1.6-.2-3.6.8-5.6 2.6-1 .9-1.7 2-2.3 3.2zm10 39.1-6.2-.1s3-16.7 12.5-19.5c1.8-.5 3.7-1 5.7-1.3l4-.8c.1-1.6-.5-3.6-1.3-5.9-.6-1.7-1.2-3.5-1.5-5.5-.6-3.9.4-7.3 3-9.6 3-2.9 7.9-3.8 13.4-2.5 3.2.7 5.5 2.2 7.6 3.6 2.9 2 4.6 3 8.2.5 4.3-2.9-1.4-14.3-4.4-21l11.3-4.6c1.5 3.3 8.8 20.3 4 30a11.5 11.5 0 0 1-8.1 6.2c-8 1.8-12.6-1.3-16-3.6-1.6-1-3-1.9-4.6-2.3-10.6-3 4.2 12.6-2.7 19.6-4.2 4.2-14.4 5.3-15 5.5-6.6 1.6-10 11.3-10 11.3z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M44 38.8c-.2 2.2-.3 3.5.3 6.4 2.7 2 8.7 2 8.7 2l-.6-2v-.3c-6.1-3-8.4-6.1-8.4-6.1zm-12.5 9.8-10.3-5 5.1-7.5 8.2 5.4zm-15.2-14A26 26 0 0 1 5 28.9l5.2-6c1.6 1.2 5 3.5 7.2 3.8l-1.1 7.9zM25.6 21.3 18 18.8a18 18 0 0 0 .7-8.3l7.9-1.3c.6 4 .3 8.2-1 12zM73 15.3l7.9-1.7L83 23.9l-7.8 1.7zM92.5 17.8 87 12c2.8-2.8 3.5-6.3 3.5-6.4L98.4 7c-.1.6-1.1 6.3-6 10.9zM95.5 48.6l7-2.2 2.3 7.7-7 2.1zM97.5 113l-7.9-1c.3-2.7-1.8-6.2-2.4-7l6.4-4.8c.5.6 4.7 6.4 4 12.8zM120.4 102.9c-3-.5-6-.6-9.1-.5l-.3-8c3.5-.2 7 0 10.6.6l-1.2 7.9zM109.6 113.9l5.6-5.7 7.8 7.6-5.6 5.7zM93.1 63.3 99 70l-6.6 5.8-5.8-6.6z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt;&lt;strong&gt;Celebration&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; This web feature is now available in all three browser engines! &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;trigonometric-functions&quot;&gt;Trigonometric functions &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-trig-functions/#trigonometric-functions&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In CSS it’s possible to write &lt;a href=&quot;https://web.dev/learn/css/functions/#mathematical-expressions&quot;&gt;mathematical expressions&lt;/a&gt;. At the base sits the &lt;code&gt;calc()&lt;/code&gt; function to do calculations, but most likely you’ve also heard of &lt;a href=&quot;https://web.dev/min-max-clamp/&quot;&gt;&lt;code&gt;min()&lt;/code&gt;, &lt;code&gt;max()&lt;/code&gt;, and &lt;code&gt;clamp()&lt;/code&gt;&lt;/a&gt; as well.&lt;/p&gt;
&lt;p&gt;Joining these functions in Chrome 111 are the trigonometric functions &lt;code&gt;sin()&lt;/code&gt;, &lt;code&gt;cos()&lt;/code&gt;, &lt;code&gt;tan()&lt;/code&gt;, &lt;code&gt;asin()&lt;/code&gt;, &lt;code&gt;acos()&lt;/code&gt;, &lt;code&gt;atan()&lt;/code&gt;, and &lt;code&gt;atan2()&lt;/code&gt;. These functions are &lt;a href=&quot;https://www.w3.org/TR/css-values-4/#trig-funcs&quot; rel=&quot;noopener&quot;&gt;defined in the CSS Values and Units Module Level 4&lt;/a&gt; and are available in all browsers.&lt;/p&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 111, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      111
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 108, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      108
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 111, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      111
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 15.4, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      15.4
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/CSS/cos#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;h3 id=&quot;sin,-cos,-and-tan&quot;&gt;&lt;code&gt;sin()&lt;/code&gt;, &lt;code&gt;cos()&lt;/code&gt;, and &lt;code&gt;tan()&lt;/code&gt; &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-trig-functions/#sin,-cos,-and-tan&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The core three “trig functions” are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cos()&lt;/code&gt;: Returns the cosine of an angle, which is a value between &lt;code&gt;-1&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sin()&lt;/code&gt;: Returns the sine of an angle, which is a value between &lt;code&gt;-1&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tan()&lt;/code&gt;: Returns the tangent of an angle, which is a value between &lt;code&gt;−∞&lt;/code&gt; and &lt;code&gt;+∞&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unlike their JavaScript counterparts, these functions accept both angles and radians as their argument.&lt;/p&gt;
&lt;p&gt;In the demo below, these functions are used to draw the lines that make up the triangle surrounding the set &lt;code&gt;--angle&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The “hypotenuse” &lt;em&gt;(yellow line)&lt;/em&gt; is a line from the center of the circle to the position of the dot. Its length is equal to the &lt;code&gt;--radius&lt;/code&gt; of the circle.&lt;/li&gt;
&lt;li&gt;The “adjacent” &lt;em&gt;(red line)&lt;/em&gt; is a line from the center of the circle along the X-axis. Its length is equal to the &lt;code&gt;--radius&lt;/code&gt; multiplied by the cosine of the &lt;code&gt;--angle&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The “opposite” &lt;em&gt;(blue line)&lt;/em&gt; is a line from the center of the circle along the Y-axis. Its length is equal to the &lt;code&gt;--radius&lt;/code&gt; multiplied by the sine of the &lt;code&gt;--angle&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;tan()&lt;/code&gt; function of the &lt;code&gt;--angle&lt;/code&gt; is used to draw the green line from the dot towards the X-axis.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 740px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/web-dot-dev/embed/NWLxROo?height=740&amp;theme-id=dark&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen NWLxROo by web-dot-dev on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/web-dot-dev/embed/NWLxROo&quot;&gt;Pen NWLxROo by web-dot-dev on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; For a good introduction on Trigonometry go check &lt;a href=&quot;https://www.mathsisfun.com/sine-cosine-tangent.html&quot;&gt;Math is Fun&lt;/a&gt; &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;asin,-acos,-atan,-and-atan2&quot;&gt;&lt;code&gt;asin()&lt;/code&gt;, &lt;code&gt;acos()&lt;/code&gt;, &lt;code&gt;atan()&lt;/code&gt;, and &lt;code&gt;atan2()&lt;/code&gt; &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-trig-functions/#asin,-acos,-atan,-and-atan2&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The “arc” or “inverse” counterparts to &lt;code&gt;sin()&lt;/code&gt;, &lt;code&gt;cos()&lt;/code&gt;, and &lt;code&gt;tan()&lt;/code&gt; are &lt;code&gt;asin()&lt;/code&gt;, &lt;code&gt;acos()&lt;/code&gt;, and &lt;code&gt;atan()&lt;/code&gt; respectively. These functions do the calculation in the opposite direction: they take a numeric value as their argument and return the corresponding angle for it.&lt;/p&gt;
&lt;p&gt;Finally there’s &lt;code&gt;atan2()&lt;/code&gt; which accepts two arguments &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt;. The function returns the angle between the positive X-axis and the point &lt;code&gt;(B,A)&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;examples&quot;&gt;Examples &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-trig-functions/#examples&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are various use-cases for these functions. What follows is a small selection.&lt;/p&gt;
&lt;h3 id=&quot;move-items-on-a-circular-path-around-a-central-point&quot;&gt;Move items on a circular path around a central point &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-trig-functions/#move-items-on-a-circular-path-around-a-central-point&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the demo below, the dots revolve around a central point. Instead of rotating each dot around its own center and then moving it outwards, each dot is translated on the X and Y axes. The distances on the X and Y axes are determined by taking the &lt;code&gt;cos()&lt;/code&gt; and, respectively, the &lt;code&gt;sin()&lt;/code&gt; of the &lt;code&gt;--angle&lt;/code&gt; into account.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20vmin&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token selector&quot;&gt;.dot&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--angle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 30deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* Translation on X-axis */&lt;/span&gt;&lt;br /&gt;             &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--radius&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;             &lt;span class=&quot;token comment&quot;&gt;/* Translation on Y-axis */&lt;/span&gt;&lt;br /&gt;             &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--radius&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * -1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 600px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/web-dot-dev/embed/ExePgOg?height=600&amp;theme-id=dark&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen ExePgOg by web-dot-dev on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/web-dot-dev/embed/ExePgOg&quot;&gt;Pen ExePgOg by web-dot-dev on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;To distribute the dots evenly around the central point, each dot is given an additional offset based on its &lt;code&gt;nth-child&lt;/code&gt; index. For example, if there are three dots, there’s a distance of &lt;code&gt;120deg&lt;/code&gt; (= &lt;code&gt;360deg / 3&lt;/code&gt;) between each dot.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first child element out of three gets offset by &lt;code&gt;0 x 120deg&lt;/code&gt; = &lt;code&gt;0deg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The second child element out of three gets offset by &lt;code&gt;1 x 120deg&lt;/code&gt; = &lt;code&gt;120deg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The third child element out of three gets offset by &lt;code&gt;2 x 120deg&lt;/code&gt; = &lt;code&gt;240deg&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;rotate-an-element-to-face-its-origin&quot;&gt;Rotate an element to face its origin &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-trig-functions/#rotate-an-element-to-face-its-origin&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;atan2()&lt;/code&gt; function calculates the relative angle from one point to another. The function accepts two comma-separated values as its parameters: the &lt;code&gt;y&lt;/code&gt; and &lt;code&gt;x&lt;/code&gt; position of the other point, relative to the originating point which sits at origin &lt;code&gt;0,0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With the calculated value it’s possible to rotate elements so that they face each other, by using the &lt;a href=&quot;https://web.dev/css-individual-transform-properties/&quot;&gt;Individual Transform Properties&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the example below, the boxes are rotated so that they face the location of the mouse. The mouse position is synced to a custom property through JavaScript.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;div.box&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--my-x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 200&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--my-y&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 300&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;/* Position the box inside its parent */&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;aspect-ratio&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--my-x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * 1px&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--my-y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * 1px&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;/* Rotate so that the box faces the mouse position */&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;/* For this, take the box its own position and size (25 = half the width) into account */&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;atan2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--mouse-x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; - &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--my-x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; - 25&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--mouse-y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; - &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--my-y&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; - 25&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * -1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 720px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/web-dot-dev/embed/dyqGpQV?height=720&amp;theme-id=dark&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen dyqGpQV by web-dot-dev on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/web-dot-dev/embed/dyqGpQV&quot;&gt;Pen dyqGpQV by web-dot-dev on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;h3 id=&quot;community-highlight&quot;&gt;Community highlight &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-trig-functions/#community-highlight&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As demonstrated in this &lt;a href=&quot;https://codepen.io/thebabydino/pen/wvybyMo&quot; rel=&quot;noopener&quot;&gt;Animated Möbius strip by Ana Tudor&lt;/a&gt;, &lt;code&gt;cos()&lt;/code&gt; and &lt;code&gt;sin()&lt;/code&gt; can be used for more than just translations. Here their outcome is used to manipulate the the &lt;code&gt;s&lt;/code&gt; and &lt;code&gt;l&lt;/code&gt; components of &lt;a href=&quot;https://developer.chrome.com/articles/high-definition-css-color-guide/#hsl&quot; rel=&quot;noopener&quot;&gt;the &lt;code&gt;hsl()&lt;/code&gt; color function&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 600px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/thebabydino/embed/wvybyMo?height=600&amp;theme-id=dark&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen wvybyMo by thebabydino on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/thebabydino/embed/wvybyMo&quot;&gt;Pen wvybyMo by thebabydino on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href=&quot;https://unsplash.com/@tamanna_rumee&quot; rel=&quot;noopener&quot;&gt;Tamanna Rumee&lt;/a&gt; on &lt;a href=&quot;https://unsplash.com/photos/7OCUyev2M9E&quot; rel=&quot;noopener&quot;&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
</content>
    <author>
      <name>Bramus</name>
    </author>
  </entry>
  
  <entry>
    <title>The large, small, and dynamic viewport units</title>
    <link href="https://web.dev/viewport-units/"/>
    <updated>2022-11-29T00:00:00Z</updated>
    <id>https://web.dev/viewport-units/</id>
    <content type="html" mode="escaped">&lt;aside class=&quot;aside flow bg-state-good-bg color-state-good-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 128 128&quot; style=&quot;enable-background:new 0 0 128 128&quot; xml:space=&quot;preserve&quot;&gt;&lt;path d=&quot;M7.5 123.3c2.2 2.4 11.6-1.9 19-5.3C32 115.4 54 106.3 65 101.6c3-1.2 7.3-2.9 10.4-7 2.8-3.6 10-19-4.6-34.7-15-16-30.4-11.5-36.2-7.5A28.5 28.5 0 0 0 27.3 63c-5.2 11.6-12.7 32.9-15.7 41.3-2.3 6.1-6.4 16.5-4.1 19z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M18 86.8s.7 6.5 6.1 14.6c6.3 9.6 15 11.2 15 11.2l-5.8 2.4s-6.5-2-12.7-10.4c-3.8-5.3-5-11.6-5-11.6l2.3-6.2zm-5.6 15.4s1.5 5.6 4.7 9.7c3.8 5 8.6 6.5 8.6 6.5l-4.5 2s-3.3-.8-7-5.5c-2.9-3.5-3.7-7.6-3.7-7.6l1.9-5.1z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 116.4c-.2-.5-.2-1 0-1.4l25.4-53 4.2 16-26.8 38.7c-.7 1-2.3 1-2.8-.2z&quot; style=&quot;opacity:.44&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M41.6 83.2c12 14 25.5 12.2 30 8.6 4.5-3.5 8.1-15.6-3.7-29.3C55.3 48.2 41.3 52.2 38 55.3s-7.4 15.1 3.5 27.9z&quot; style=&quot;fill: var(--color-state-good-bg);&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M82.5 89c-4.3-3.7-6.6-3-9.7-1.8a26 26 0 0 1-18.9 0l2.6-6.2c5 1.7 8.7 1 12-1 4-2.4 9.6-5.6 18.3 1.6 3.6 3 7.3 5.1 10 4.2 2-.7 3-3.6 3.6-6l.2-1.3c.4-3.7 1.2-11.6 7.1-15.7 6.4-4.3 13-4.3 13-4.3l1.2 12c-3-.5-5.2.1-7 1-6.7 3.8-.8 18.2-11.3 23-10.1 4.8-18.4-3.3-21-5.6zM45.4 73.7l-4.3-3.9c8-8.9 5.8-15.4 4.3-20.2A26.4 26.4 0 0 1 44 38.8c-3-3.8-4.4-7.8-4.5-8-1.9-5.7-.5-11.2 2.8-16.4C48.7 4 60.5 4 60.5 4l4 10.5c-3-.1-12.8 0-15.8 4.8-3.8 6-1.3 9.6-1.2 10 .8-1 1.5-1.7 2.2-2.3 4.8-4.2 9-4.8 11.6-4.6a11 11 0 0 1 7.6 4.2c2 2.7 3 6.2 2.3 9.4a11 11 0 0 1-5.8 7.4 16 16 0 0 1-13 1.5v.3l.6 2c1.8 5.4 5 14.1-7.6 26.5zm7.4-37.5c.5.4 1.1.8 1.8 1 2 .8 4.4.6 7-.8 1.5-.9 1.7-1.7 1.7-2 .2-.9 0-2-.7-2.8a2.8 2.8 0 0 0-2-1.2c-1.6-.2-3.6.8-5.6 2.6-1 .9-1.7 2-2.3 3.2zm10 39.1-6.2-.1s3-16.7 12.5-19.5c1.8-.5 3.7-1 5.7-1.3l4-.8c.1-1.6-.5-3.6-1.3-5.9-.6-1.7-1.2-3.5-1.5-5.5-.6-3.9.4-7.3 3-9.6 3-2.9 7.9-3.8 13.4-2.5 3.2.7 5.5 2.2 7.6 3.6 2.9 2 4.6 3 8.2.5 4.3-2.9-1.4-14.3-4.4-21l11.3-4.6c1.5 3.3 8.8 20.3 4 30a11.5 11.5 0 0 1-8.1 6.2c-8 1.8-12.6-1.3-16-3.6-1.6-1-3-1.9-4.6-2.3-10.6-3 4.2 12.6-2.7 19.6-4.2 4.2-14.4 5.3-15 5.5-6.6 1.6-10 11.3-10 11.3z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M44 38.8c-.2 2.2-.3 3.5.3 6.4 2.7 2 8.7 2 8.7 2l-.6-2v-.3c-6.1-3-8.4-6.1-8.4-6.1zm-12.5 9.8-10.3-5 5.1-7.5 8.2 5.4zm-15.2-14A26 26 0 0 1 5 28.9l5.2-6c1.6 1.2 5 3.5 7.2 3.8l-1.1 7.9zM25.6 21.3 18 18.8a18 18 0 0 0 .7-8.3l7.9-1.3c.6 4 .3 8.2-1 12zM73 15.3l7.9-1.7L83 23.9l-7.8 1.7zM92.5 17.8 87 12c2.8-2.8 3.5-6.3 3.5-6.4L98.4 7c-.1.6-1.1 6.3-6 10.9zM95.5 48.6l7-2.2 2.3 7.7-7 2.1zM97.5 113l-7.9-1c.3-2.7-1.8-6.2-2.4-7l6.4-4.8c.5.6 4.7 6.4 4 12.8zM120.4 102.9c-3-.5-6-.6-9.1-.5l-.3-8c3.5-.2 7 0 10.6.6l-1.2 7.9zM109.6 113.9l5.6-5.7 7.8 7.6-5.6 5.7zM93.1 63.3 99 70l-6.6 5.8-5.8-6.6z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt;&lt;strong&gt;Celebration&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; This web feature is now available in all three browser engines! &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;the-viewport-and-its-units&quot;&gt;The viewport and its units &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/viewport-units/#the-viewport-and-its-units&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To size something as tall as the viewport, you can use the &lt;code&gt;vw&lt;/code&gt; and &lt;code&gt;vh&lt;/code&gt; units.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;vw&lt;/code&gt; = 1% of the width of the viewport size.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vh&lt;/code&gt; = 1% of the height of the viewport size.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Give an element a width of &lt;code&gt;100vw&lt;/code&gt; and a height of &lt;code&gt;100vh&lt;/code&gt;, and it will cover the viewport entirely.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A light blue element set to be 100vw by 100vh, covering the entire viewport. The viewport itself is indicated using a blue dashed border.&quot; class=&quot;screenshot&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/IpR2qrX8ENZ1MRMJfehn.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;A light blue element set to be 100vw by 100vh, covering the entire viewport.&lt;br /&gt;The viewport itself is indicated using a blue dashed border.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The &lt;code&gt;vw&lt;/code&gt; and &lt;code&gt;vh&lt;/code&gt; units landed in browsers with these additional units&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;vi&lt;/code&gt; = 1% of the size of the viewport’s inline axis.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vb&lt;/code&gt; = 1% of the size of the viewport’s block axis.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vmin&lt;/code&gt; = the smaller of &lt;code&gt;vw&lt;/code&gt; or &lt;code&gt;vh&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vmax&lt;/code&gt; = the larger of &lt;code&gt;vw&lt;/code&gt; or &lt;code&gt;vh&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These units have good browser support.&lt;/p&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 20, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      20
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 19, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      19
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 12, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      12
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 6, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      6
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;the-need-for-new-viewport-units&quot;&gt;The need for new viewport units &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/viewport-units/#the-need-for-new-viewport-units&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While the existing units work well on desktop, it’s a different story on mobile devices. There, the viewport size is influenced by the presence or absence of dynamic toolbars. These are user interfaces such as address bars and tab bars.&lt;/p&gt;
&lt;p&gt;Although the viewport size can change, the &lt;code&gt;vw&lt;/code&gt; and &lt;code&gt;vh&lt;/code&gt; sizes do not. As a result, elements sized to be &lt;code&gt;100vh&lt;/code&gt; tall will bleed out of the viewport.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;100vh on mobile is too tall on load.&quot; class=&quot;screenshot&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/bWbl71iEuR5Gu9a2eAxD.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;100vh on mobile is too tall on load.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;When scrolling down these dynamic toolbars will retract. In this state, elements sized to be &lt;code&gt;100vh&lt;/code&gt; tall will cover the entire viewport.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;100vh on mobile is “correct” when the User-Agent user interfaces are retracted.&quot; class=&quot;screenshot&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/kuGqSsKtDI1PNUDEVx8n.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;100vh on mobile is “correct” when the User-Agent user interfaces are retracted.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To solve this problem, the various states of the viewport have been specified at the CSS Working Group.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Large viewport&lt;/strong&gt;: The viewport sized assuming any UA interfaces that are dynamically expanded and retracted to be retracted.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Small Viewport&lt;/strong&gt;: The viewport sized assuming any UA interfaces that are dynamically expanded and retracted to be expanded.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
  &lt;img alt=&quot;Visualizations of the large and small viewports.&quot; class=&quot;screenshot&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ZwgiN6CI2ERg04ntpnNG.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;Visualizations of the large and small viewports.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The new viewports also have units assigned to them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Units representing the large viewport have the &lt;code&gt;lv&lt;/code&gt; prefix. The units are &lt;code&gt;lvw&lt;/code&gt;, &lt;code&gt;lvh&lt;/code&gt;, &lt;code&gt;lvi&lt;/code&gt;, &lt;code&gt;lvb&lt;/code&gt;, &lt;code&gt;lvmin&lt;/code&gt;, and &lt;code&gt;lvmax&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Units representing the small viewport have the &lt;code&gt;sv&lt;/code&gt; prefix. The units are &lt;code&gt;svw&lt;/code&gt;, &lt;code&gt;svh&lt;/code&gt;, &lt;code&gt;svi&lt;/code&gt;, &lt;code&gt;svb&lt;/code&gt;, &lt;code&gt;svmin&lt;/code&gt;, and &lt;code&gt;svmax&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The sizes of these viewport-percentage units are fixed (and therefore stable) unless the viewport itself is resized.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;Two mobile browser visualizations positioned next to each other. One has an element sized to be 100svh and the other 100lvh.&quot; class=&quot;screenshot&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/ScGKMyzS1WyS7ByoVvn8.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;Two mobile browser visualizations positioned next to each other.&lt;br /&gt;One has an element sized to be 100svh and the other 100lvh.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In addition to the large and small viewports, there‘s also a dynamic viewport which has dynamic consideration of the UA UI:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When the dynamic toolbars are expanded, the dynamic viewport is equal to the size of the small viewport.&lt;/li&gt;
&lt;li&gt;When the dynamic toolbars are retracted, the dynamic viewport is equal to the size of the large viewport.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Its accompanied units have the &lt;code&gt;dv&lt;/code&gt; prefix: &lt;code&gt;dvw&lt;/code&gt;, &lt;code&gt;dvh&lt;/code&gt;, &lt;code&gt;dvi&lt;/code&gt;, &lt;code&gt;dvb&lt;/code&gt;, &lt;code&gt;dvmin&lt;/code&gt;, and &lt;code&gt;dvmax&lt;/code&gt;. Their sizes are clamped between their &lt;code&gt;lv*&lt;/code&gt; and &lt;code&gt;sv*&lt;/code&gt; counterparts.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;100dvh adapts itself to be either the large or small viewport size.&quot; class=&quot;screenshot&quot; decoding=&quot;async&quot; height=&quot;450&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/UCWsRe1PmYg7nvAvTu86.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;100dvh adapts itself to be either the large or small viewport size.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;These units ship in Chrome 108, joining Safari and Firefox which already have support.&lt;/p&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 108, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      108
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 101, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      101
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 108, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      108
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 15.4, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      15.4
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; In browsers that don’t have dynamic UA UI–such as Chrome on desktop–the size of the large, small, and dynamic viewports are the same. &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;caveats&quot;&gt;Caveats &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/viewport-units/#caveats&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There‘s a few caveats to know about Viewport Units:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;None of the viewport units take the size of scrollbars into account. On systems that have classic scrollbars enabled, an element sized to &lt;code&gt;100vw&lt;/code&gt; will therefore be a little bit too wide. This is as &lt;a href=&quot;https://www.w3.org/TR/css-values-4/#viewport-relative-lengths:~:text=In%20all%20cases%2C%20scrollbars%20are%20assumed%20not%20to%20exist.&quot; rel=&quot;noopener&quot;&gt;per specification&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The values for the dynamic viewport do not update at 60fps. In all browsers updating is throttled as the UA UI expands or retracts. Some browsers even debounce updating entirely depending on the gesture (a slow scroll versus a swipe) used.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The on-screen keyboard (also known as the virtual keyboard) is not considered part of the UA UI. Therefore it does not affect the size of the viewport units. In Chrome &lt;a href=&quot;https://developer.chrome.com/blog/viewport-resize-behavior/#opting-in-to-a-different-behavior&quot; rel=&quot;noopener&quot;&gt;you can opt-in to a behavior where the presence of the virtual keyboard does affect the viewport units&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;additional-resources&quot;&gt;Additional resources &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/viewport-units/#additional-resources&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To learn more about viewports and these units check out &lt;a href=&quot;https://www.youtube.com/watch?v=xl9R8aTOW_I&quot; rel=&quot;noopener&quot;&gt;this episode of HTTP 203&lt;/a&gt;. In it, &lt;a href=&quot;https://web.dev/authors/bramus/&quot;&gt;Bramus&lt;/a&gt; tells &lt;a href=&quot;https://web.dev/authors/jakearchibald/&quot;&gt;Jake&lt;/a&gt; all about the various viewports and explains how exactly the sizes of these units are determined.&lt;/p&gt;
&lt;div class=&quot;youtube&quot;&gt;  &lt;lite-youtube videoid=&quot;xl9R8aTOW_I&quot;&gt;  &lt;/lite-youtube&gt;&lt;/div&gt;
&lt;p&gt;Additional reading material:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.w3.org/TR/css-values-4/#viewport-relative-lengths&quot; rel=&quot;noopener&quot;&gt;CSS Values 4 Specification: Viewport-relative lengths&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://chromestatus.com/feature/5170718078140416?context=myfeatures&quot; rel=&quot;noopener&quot;&gt;ChromeStatus Entry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/web-platform-tests/interop-2022-viewport/blob/main/explainers/layout-viewport.md&quot; rel=&quot;noopener&quot;&gt;Layout Viewport explainer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/web-platform-tests/interop-2022-viewport/blob/main/explainers/viewport-units.md&quot; rel=&quot;noopener&quot;&gt;Viewport Units explainer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
    <author>
      <name>Bramus</name>
    </author>
  </entry>
  
  <entry>
    <title>CSS Animated Grid Layouts</title>
    <link href="https://web.dev/css-animated-grid-layouts/"/>
    <updated>2022-10-25T00:00:00Z</updated>
    <id>https://web.dev/css-animated-grid-layouts/</id>
    <content type="html" mode="escaped">&lt;aside class=&quot;aside flow bg-state-good-bg color-state-good-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 128 128&quot; style=&quot;enable-background:new 0 0 128 128&quot; xml:space=&quot;preserve&quot;&gt;&lt;path d=&quot;M7.5 123.3c2.2 2.4 11.6-1.9 19-5.3C32 115.4 54 106.3 65 101.6c3-1.2 7.3-2.9 10.4-7 2.8-3.6 10-19-4.6-34.7-15-16-30.4-11.5-36.2-7.5A28.5 28.5 0 0 0 27.3 63c-5.2 11.6-12.7 32.9-15.7 41.3-2.3 6.1-6.4 16.5-4.1 19z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M18 86.8s.7 6.5 6.1 14.6c6.3 9.6 15 11.2 15 11.2l-5.8 2.4s-6.5-2-12.7-10.4c-3.8-5.3-5-11.6-5-11.6l2.3-6.2zm-5.6 15.4s1.5 5.6 4.7 9.7c3.8 5 8.6 6.5 8.6 6.5l-4.5 2s-3.3-.8-7-5.5c-2.9-3.5-3.7-7.6-3.7-7.6l1.9-5.1z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 116.4c-.2-.5-.2-1 0-1.4l25.4-53 4.2 16-26.8 38.7c-.7 1-2.3 1-2.8-.2z&quot; style=&quot;opacity:.44&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M41.6 83.2c12 14 25.5 12.2 30 8.6 4.5-3.5 8.1-15.6-3.7-29.3C55.3 48.2 41.3 52.2 38 55.3s-7.4 15.1 3.5 27.9z&quot; style=&quot;fill: var(--color-state-good-bg);&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M82.5 89c-4.3-3.7-6.6-3-9.7-1.8a26 26 0 0 1-18.9 0l2.6-6.2c5 1.7 8.7 1 12-1 4-2.4 9.6-5.6 18.3 1.6 3.6 3 7.3 5.1 10 4.2 2-.7 3-3.6 3.6-6l.2-1.3c.4-3.7 1.2-11.6 7.1-15.7 6.4-4.3 13-4.3 13-4.3l1.2 12c-3-.5-5.2.1-7 1-6.7 3.8-.8 18.2-11.3 23-10.1 4.8-18.4-3.3-21-5.6zM45.4 73.7l-4.3-3.9c8-8.9 5.8-15.4 4.3-20.2A26.4 26.4 0 0 1 44 38.8c-3-3.8-4.4-7.8-4.5-8-1.9-5.7-.5-11.2 2.8-16.4C48.7 4 60.5 4 60.5 4l4 10.5c-3-.1-12.8 0-15.8 4.8-3.8 6-1.3 9.6-1.2 10 .8-1 1.5-1.7 2.2-2.3 4.8-4.2 9-4.8 11.6-4.6a11 11 0 0 1 7.6 4.2c2 2.7 3 6.2 2.3 9.4a11 11 0 0 1-5.8 7.4 16 16 0 0 1-13 1.5v.3l.6 2c1.8 5.4 5 14.1-7.6 26.5zm7.4-37.5c.5.4 1.1.8 1.8 1 2 .8 4.4.6 7-.8 1.5-.9 1.7-1.7 1.7-2 .2-.9 0-2-.7-2.8a2.8 2.8 0 0 0-2-1.2c-1.6-.2-3.6.8-5.6 2.6-1 .9-1.7 2-2.3 3.2zm10 39.1-6.2-.1s3-16.7 12.5-19.5c1.8-.5 3.7-1 5.7-1.3l4-.8c.1-1.6-.5-3.6-1.3-5.9-.6-1.7-1.2-3.5-1.5-5.5-.6-3.9.4-7.3 3-9.6 3-2.9 7.9-3.8 13.4-2.5 3.2.7 5.5 2.2 7.6 3.6 2.9 2 4.6 3 8.2.5 4.3-2.9-1.4-14.3-4.4-21l11.3-4.6c1.5 3.3 8.8 20.3 4 30a11.5 11.5 0 0 1-8.1 6.2c-8 1.8-12.6-1.3-16-3.6-1.6-1-3-1.9-4.6-2.3-10.6-3 4.2 12.6-2.7 19.6-4.2 4.2-14.4 5.3-15 5.5-6.6 1.6-10 11.3-10 11.3z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M44 38.8c-.2 2.2-.3 3.5.3 6.4 2.7 2 8.7 2 8.7 2l-.6-2v-.3c-6.1-3-8.4-6.1-8.4-6.1zm-12.5 9.8-10.3-5 5.1-7.5 8.2 5.4zm-15.2-14A26 26 0 0 1 5 28.9l5.2-6c1.6 1.2 5 3.5 7.2 3.8l-1.1 7.9zM25.6 21.3 18 18.8a18 18 0 0 0 .7-8.3l7.9-1.3c.6 4 .3 8.2-1 12zM73 15.3l7.9-1.7L83 23.9l-7.8 1.7zM92.5 17.8 87 12c2.8-2.8 3.5-6.3 3.5-6.4L98.4 7c-.1.6-1.1 6.3-6 10.9zM95.5 48.6l7-2.2 2.3 7.7-7 2.1zM97.5 113l-7.9-1c.3-2.7-1.8-6.2-2.4-7l6.4-4.8c.5.6 4.7 6.4 4 12.8zM120.4 102.9c-3-.5-6-.6-9.1-.5l-.3-8c3.5-.2 7 0 10.6.6l-1.2 7.9zM109.6 113.9l5.6-5.7 7.8 7.6-5.6 5.7zM93.1 63.3 99 70l-6.6 5.8-5.8-6.6z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt;&lt;strong&gt;Celebration&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; This web feature is now available in all three browser engines! &lt;/div&gt;&lt;/aside&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 107, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      107
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 66, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      66
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 107, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      107
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 16, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      16
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;value-interpolation-in-css&quot;&gt;Value Interpolation in CSS &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-animated-grid-layouts/#value-interpolation-in-css&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In CSS you can smoothly transition properties from one value to the other using the &lt;code&gt;transition&lt;/code&gt; property.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;#target&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0.5&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; opacity ease-in-out 0.25s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token selector&quot;&gt;#target:hover&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The rendering engine will automatically detect the type of the targeted property’s value, and use that information to smoothly transition to the new value.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Transitioning &lt;code&gt;opacity&lt;/code&gt; from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;1&lt;/code&gt;?
That’s a numerical interpolation.&lt;/li&gt;
&lt;li&gt;Transitioning &lt;code&gt;background-color&lt;/code&gt; from &lt;code&gt;white&lt;/code&gt; to &lt;code&gt;black&lt;/code&gt;?
Fade between the source and target colors.&lt;/li&gt;
&lt;li&gt;Transitioning &lt;code&gt;width&lt;/code&gt;?
Interpolate numerically, converting units along the way if needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The same applies to CSS animations, where the browser will do value interpolation between keyframes.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; When using Custom Properties, &lt;a href=&quot;https://web.dev/at-property&quot;&gt;use &lt;code&gt;@property&lt;/code&gt;&lt;/a&gt; to indicate which type they are. That way the browser knows how to transition from one value to the other. &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;interpolating-grid-template-columns-and-grid-template-rows&quot;&gt;Interpolating &lt;code&gt;grid-template-columns&lt;/code&gt; and &lt;code&gt;grid-template-rows&lt;/code&gt; &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-animated-grid-layouts/#interpolating-grid-template-columns-and-grid-template-rows&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Thanks to our contributors at Microsoft, Chrome–as of version 107–is able to interpolate &lt;code&gt;grid-template-columns&lt;/code&gt; and &lt;code&gt;grid-template-rows&lt;/code&gt; values.&lt;/p&gt;
&lt;p&gt;Grid layouts can smoothly transition between states, instead of snapping at the halfway point of an animation or transition.&lt;/p&gt;
&lt;p&gt;In the demo below a grid is showing several avatars. To conserve space, the avatars are laid out on top of each other by limiting the width of each column using &lt;code&gt;grid-template-columns&lt;/code&gt;. On hover, each column is given more space.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.avatars&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; grid&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;gap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0.35em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;grid-auto-flow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; column&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;grid-template-columns&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 2em&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; all ease-in-out 0.25s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token selector&quot;&gt;.avatars:hover&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;grid-template-columns&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 4em&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;With the &lt;code&gt;transition&lt;/code&gt; property in place, the grid smoothly interpolates between values.&lt;/p&gt;
&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 480px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/web-dot-dev/embed/XWqVowx?height=480&amp;theme-id=light&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen XWqVowx by web-dot-dev on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/web-dot-dev/embed/XWqVowx&quot;&gt;Pen XWqVowx by web-dot-dev on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;The effect also applies to animations that change the &lt;code&gt;grid-template-columns&lt;/code&gt; or &lt;code&gt;grid-template-rows&lt;/code&gt; values.&lt;/p&gt;
&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 780px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/web-dot-dev/embed/jOxRdzw?height=780&amp;theme-id=light&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen jOxRdzw by web-dot-dev on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/web-dot-dev/embed/jOxRdzw&quot;&gt;Pen jOxRdzw by web-dot-dev on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;Photo by &lt;a href=&quot;https://unsplash.com/@namzo&quot; rel=&quot;noopener&quot;&gt;Ernest Ojeh&lt;/a&gt; on &lt;a href=&quot;https://unsplash.com/photos/rTpPZD9PAk4&quot; rel=&quot;noopener&quot;&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
</content>
    <author>
      <name>Bramus</name>
    </author>
  </entry>
  
  <entry>
    <title>Finer grained control over CSS transforms with individual transform properties</title>
    <link href="https://web.dev/css-individual-transform-properties/"/>
    <updated>2022-08-02T00:00:00Z</updated>
    <id>https://web.dev/css-individual-transform-properties/</id>
    <content type="html" mode="escaped">&lt;aside class=&quot;aside flow bg-state-good-bg color-state-good-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 128 128&quot; style=&quot;enable-background:new 0 0 128 128&quot; xml:space=&quot;preserve&quot;&gt;&lt;path d=&quot;M7.5 123.3c2.2 2.4 11.6-1.9 19-5.3C32 115.4 54 106.3 65 101.6c3-1.2 7.3-2.9 10.4-7 2.8-3.6 10-19-4.6-34.7-15-16-30.4-11.5-36.2-7.5A28.5 28.5 0 0 0 27.3 63c-5.2 11.6-12.7 32.9-15.7 41.3-2.3 6.1-6.4 16.5-4.1 19z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M18 86.8s.7 6.5 6.1 14.6c6.3 9.6 15 11.2 15 11.2l-5.8 2.4s-6.5-2-12.7-10.4c-3.8-5.3-5-11.6-5-11.6l2.3-6.2zm-5.6 15.4s1.5 5.6 4.7 9.7c3.8 5 8.6 6.5 8.6 6.5l-4.5 2s-3.3-.8-7-5.5c-2.9-3.5-3.7-7.6-3.7-7.6l1.9-5.1z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M10 116.4c-.2-.5-.2-1 0-1.4l25.4-53 4.2 16-26.8 38.7c-.7 1-2.3 1-2.8-.2z&quot; style=&quot;opacity:.44&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M41.6 83.2c12 14 25.5 12.2 30 8.6 4.5-3.5 8.1-15.6-3.7-29.3C55.3 48.2 41.3 52.2 38 55.3s-7.4 15.1 3.5 27.9z&quot; style=&quot;fill: var(--color-state-good-bg);&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M82.5 89c-4.3-3.7-6.6-3-9.7-1.8a26 26 0 0 1-18.9 0l2.6-6.2c5 1.7 8.7 1 12-1 4-2.4 9.6-5.6 18.3 1.6 3.6 3 7.3 5.1 10 4.2 2-.7 3-3.6 3.6-6l.2-1.3c.4-3.7 1.2-11.6 7.1-15.7 6.4-4.3 13-4.3 13-4.3l1.2 12c-3-.5-5.2.1-7 1-6.7 3.8-.8 18.2-11.3 23-10.1 4.8-18.4-3.3-21-5.6zM45.4 73.7l-4.3-3.9c8-8.9 5.8-15.4 4.3-20.2A26.4 26.4 0 0 1 44 38.8c-3-3.8-4.4-7.8-4.5-8-1.9-5.7-.5-11.2 2.8-16.4C48.7 4 60.5 4 60.5 4l4 10.5c-3-.1-12.8 0-15.8 4.8-3.8 6-1.3 9.6-1.2 10 .8-1 1.5-1.7 2.2-2.3 4.8-4.2 9-4.8 11.6-4.6a11 11 0 0 1 7.6 4.2c2 2.7 3 6.2 2.3 9.4a11 11 0 0 1-5.8 7.4 16 16 0 0 1-13 1.5v.3l.6 2c1.8 5.4 5 14.1-7.6 26.5zm7.4-37.5c.5.4 1.1.8 1.8 1 2 .8 4.4.6 7-.8 1.5-.9 1.7-1.7 1.7-2 .2-.9 0-2-.7-2.8a2.8 2.8 0 0 0-2-1.2c-1.6-.2-3.6.8-5.6 2.6-1 .9-1.7 2-2.3 3.2zm10 39.1-6.2-.1s3-16.7 12.5-19.5c1.8-.5 3.7-1 5.7-1.3l4-.8c.1-1.6-.5-3.6-1.3-5.9-.6-1.7-1.2-3.5-1.5-5.5-.6-3.9.4-7.3 3-9.6 3-2.9 7.9-3.8 13.4-2.5 3.2.7 5.5 2.2 7.6 3.6 2.9 2 4.6 3 8.2.5 4.3-2.9-1.4-14.3-4.4-21l11.3-4.6c1.5 3.3 8.8 20.3 4 30a11.5 11.5 0 0 1-8.1 6.2c-8 1.8-12.6-1.3-16-3.6-1.6-1-3-1.9-4.6-2.3-10.6-3 4.2 12.6-2.7 19.6-4.2 4.2-14.4 5.3-15 5.5-6.6 1.6-10 11.3-10 11.3z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M44 38.8c-.2 2.2-.3 3.5.3 6.4 2.7 2 8.7 2 8.7 2l-.6-2v-.3c-6.1-3-8.4-6.1-8.4-6.1zm-12.5 9.8-10.3-5 5.1-7.5 8.2 5.4zm-15.2-14A26 26 0 0 1 5 28.9l5.2-6c1.6 1.2 5 3.5 7.2 3.8l-1.1 7.9zM25.6 21.3 18 18.8a18 18 0 0 0 .7-8.3l7.9-1.3c.6 4 .3 8.2-1 12zM73 15.3l7.9-1.7L83 23.9l-7.8 1.7zM92.5 17.8 87 12c2.8-2.8 3.5-6.3 3.5-6.4L98.4 7c-.1.6-1.1 6.3-6 10.9zM95.5 48.6l7-2.2 2.3 7.7-7 2.1zM97.5 113l-7.9-1c.3-2.7-1.8-6.2-2.4-7l6.4-4.8c.5.6 4.7 6.4 4 12.8zM120.4 102.9c-3-.5-6-.6-9.1-.5l-.3-8c3.5-.2 7 0 10.6.6l-1.2 7.9zM109.6 113.9l5.6-5.7 7.8 7.6-5.6 5.7zM93.1 63.3 99 70l-6.6 5.8-5.8-6.6z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt;&lt;strong&gt;Celebration&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; This web feature is now available in all three browser engines! &lt;div class=&quot;wdi-browser-compat&quot;&gt; &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt; &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt; &lt;li class=&quot;wdi-browser-compat__item&quot;&gt; &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt; &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 104, Supported&lt;/span&gt; &lt;/span&gt; &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt; 104 &lt;/span&gt; &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt; &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt; &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 72, Supported&lt;/span&gt; &lt;/span&gt; &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt; 72 &lt;/span&gt; &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt; &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt; &lt;span class=&quot;visually-hidden&quot;&gt;Edge 104, Supported&lt;/span&gt; &lt;/span&gt; &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt; 104 &lt;/span&gt; &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt; &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt; &lt;span class=&quot;visually-hidden&quot;&gt;Safari 14.1, Supported&lt;/span&gt; &lt;/span&gt; &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt; 14.1 &lt;/span&gt; &lt;/li&gt; &lt;/ul&gt; &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/CSS/rotate#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;&lt;/aside&gt;
&lt;div class=&quot;youtube&quot;&gt;  &lt;lite-youtube videoid=&quot;oDcb3fvtETs&quot; videoStartAt=&quot;844&quot;&gt;  &lt;/lite-youtube&gt;&lt;/div&gt;
&lt;h2 id=&quot;the-css-transform-property&quot;&gt;The CSS &lt;code&gt;transform&lt;/code&gt; property &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-individual-transform-properties/#the-css-transform-property&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To apply transforms to an element, use the &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/transform&quot; rel=&quot;noopener&quot;&gt;CSS &lt;code&gt;transform&lt;/code&gt; Property&lt;/a&gt;. The property accepts one or more &lt;code&gt;&amp;lt;transform-function&amp;gt;&lt;/code&gt;s which get applied one after the other.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.target&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;50%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;30deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;1.2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The targeted element is translated by 50% on the X-axis, rotated by 30 degrees, and finally scaled up to 120%.&lt;/p&gt;
&lt;p&gt;While the &lt;code&gt;transform&lt;/code&gt; property does its work just fine, it becomes a bit tedious when you want to alter any of those values individually.&lt;/p&gt;
&lt;p&gt;To change the scale on hover, you must duplicate all functions in the transform property, even though their values remain unchanged.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.target:hover&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;50%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;30deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* Only the value of scale() changed */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h2 id=&quot;the-individual-transform-properties&quot;&gt;The individual transform properties &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-individual-transform-properties/#the-individual-transform-properties&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Shipping with Chrome 104 are individual properties for CSS transforms. The properties are &lt;code&gt;scale&lt;/code&gt;, &lt;code&gt;rotate&lt;/code&gt;, and &lt;code&gt;translate&lt;/code&gt;, which you can use to individually define those parts of a transformation.&lt;/p&gt;
&lt;p&gt;By doing so, Chrome joins Firefox and Safari which already support these properties.&lt;/p&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 104, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      104
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 72, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      72
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 104, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      104
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 14.1, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      14.1
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/CSS/scale#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; Not all transformation functions have a matching individual property, for example &lt;code&gt;skewX()&lt;/code&gt; and &lt;code&gt;matrix()&lt;/code&gt;. &lt;/div&gt;&lt;/aside&gt;
&lt;p&gt;Rewriting the preceding &lt;code&gt;transform&lt;/code&gt; example with the individual properties, your snippet becomes this:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.target&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50% 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 30deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1.2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h2 id=&quot;order-matters&quot;&gt;Order matters &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-individual-transform-properties/#order-matters&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One key difference between the original CSS &lt;code&gt;transform&lt;/code&gt; property and the new properties is the order in which the declared transformations get applied.&lt;/p&gt;
&lt;p&gt;With &lt;code&gt;transform&lt;/code&gt;, the transformation functions get applied in the order they’re written–from left (outside) to right (inside).&lt;/p&gt;
&lt;p&gt;With the individual transformation properties, the order is not the order in which they are declared.  The order is always the same: first &lt;code&gt;translate&lt;/code&gt; (outside), then &lt;code&gt;rotate&lt;/code&gt;, and then &lt;code&gt;scale&lt;/code&gt; (inside).&lt;/p&gt;
&lt;p&gt;That means both of the following code snippets give the same result:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.transform--individual&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50% 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 30deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1.2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token selector&quot;&gt;.transform--individual-alt&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 30deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 50% 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1.2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;In both cases the targeted elements will first be translated by &lt;code&gt;50%&lt;/code&gt; on the X-axis, then rotated by &lt;code&gt;30deg&lt;/code&gt;, and finally scaled by &lt;code&gt;1.2&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If one of the individual transform properties are declared along with a &lt;code&gt;transform&lt;/code&gt; property, then the individual transforms get applied first (&lt;code&gt;translate&lt;/code&gt;, &lt;code&gt;rotate&lt;/code&gt;, and then &lt;code&gt;scale&lt;/code&gt;) with the &lt;code&gt;transform&lt;/code&gt; last (inside). More details are in the spec that defines &lt;a href=&quot;https://www.w3.org/TR/css-transforms-2/#ctm&quot; rel=&quot;noopener&quot;&gt;how the transformation matrix should be calculated&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;animations&quot;&gt;Animations &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-individual-transform-properties/#animations&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The main reason these properties were added is to make animations easier. Say you want to animate an element as follows:&lt;/p&gt;
&lt;img alt=&quot;Keyframes graph.&quot; decoding=&quot;async&quot; height=&quot;745&quot; loading=&quot;lazy&quot; src=&quot;https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/Pn0t3nrqfBg6JhmYFslm.svg&quot; width=&quot;800&quot; /&gt;
&lt;h3 id=&quot;using-transform&quot;&gt;Using &lt;code&gt;transform&lt;/code&gt; &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-individual-transform-properties/#using-transform&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To implement this animation using &lt;code&gt;transform&lt;/code&gt;, you’d have to calculate all in-between values for all defined transformations, and include those in each keyframe. For example, to do a rotation at the 10% mark, the values for the other transformations must be calculated as well, because the &lt;code&gt;transform&lt;/code&gt; property needs all of them.&lt;/p&gt;
&lt;img alt=&quot;Keyframes graph with intermediate values calculated.&quot; decoding=&quot;async&quot; height=&quot;745&quot; loading=&quot;lazy&quot; src=&quot;https://web-dev.imgix.net/image/AeNB0cHNDkYPUYzDuv8gInYA9rY2/AF5n6UlhcuQ5UNKemX8M.svg&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;The resulting CSS code becomes this:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; anim&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;0%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;5%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;5%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;90deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;1.2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;10%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;10%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;180deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;1.2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;90%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;90%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;180deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;1.2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;95%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;95%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;270deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;1.2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;100%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;translateX&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;100%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;360deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token selector&quot;&gt;.target&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; anim 2s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;animation-fill-mode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; forwards&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 360px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/web-dot-dev/embed/gOeRMZV?height=360&amp;theme-id=dark&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen gOeRMZV by web-dot-dev on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/web-dot-dev/embed/gOeRMZV&quot;&gt;Pen gOeRMZV by web-dot-dev on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;h3 id=&quot;using-individual-transform-properties&quot;&gt;Using individual transform properties &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-individual-transform-properties/#using-individual-transform-properties&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;With individual transform properties this becomes much easier to write. Instead of dragging all transformations from keyframe to keyframe, you can target each transform individually. You also no longer need to calculate all those in-between values.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; anim&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;0%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0% 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;100%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100% 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;0%, 100%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;5%, 95%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1.2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;0%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;10%, 90%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 180deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;100%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 360deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token selector&quot;&gt;.target&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; anim 2s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;animation-fill-mode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; forwards&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 360px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/web-dot-dev/embed/NWYgrox?height=360&amp;theme-id=dark&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen NWYgrox by web-dot-dev on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/web-dot-dev/embed/NWYgrox&quot;&gt;Pen NWYgrox by web-dot-dev on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;h3 id=&quot;using-individual-transform-properties-and-several-keyframes&quot;&gt;Using individual transform properties and several keyframes &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-individual-transform-properties/#using-individual-transform-properties-and-several-keyframes&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To make your code modular you can split up each sub-animation into its own set of keyframes.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; move&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;0%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0% 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;100%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100% 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; scale&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;0%, 100%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;5%, 95%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1.2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; rotate&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;0%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;10%, 90%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 180deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;100%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 360deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token selector&quot;&gt;.target&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; move 2s&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; scale 2s&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rotate 2s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;animation-fill-mode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; forwards&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 360px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/web-dot-dev/embed/poLwbGR?height=360&amp;theme-id=dark&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen poLwbGR by web-dot-dev on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/web-dot-dev/embed/poLwbGR&quot;&gt;Pen poLwbGR by web-dot-dev on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;Thanks to this split you can apply each separate set of keyframes as you like because the &lt;code&gt;transform&lt;/code&gt; properties–which now have become individual properties–no longer overwrite each other. Above that you can give each transformation a different timing without needing to rewrite the whole lot.&lt;/p&gt;
&lt;h2 id=&quot;performance&quot;&gt;Performance &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-individual-transform-properties/#performance&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Animations using these new properties are just as efficient as animations of the existing &lt;code&gt;transform&lt;/code&gt; property.&lt;/p&gt;
&lt;p&gt;Animations of &lt;code&gt;translate&lt;/code&gt;, &lt;code&gt;rotate&lt;/code&gt;, and &lt;code&gt;scale&lt;/code&gt; run on the compositor the same way that animations of &lt;code&gt;transform&lt;/code&gt; do, so they’re good for animation performance in &lt;a href=&quot;https://web.dev/animations-guide/&quot;&gt;the same way that &lt;code&gt;transform&lt;/code&gt; is&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;These new properties also work with the &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/will-change&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;will-change&lt;/code&gt;&lt;/a&gt; property. In general, it’s best to avoid overusing &lt;code&gt;will-change&lt;/code&gt; by using it on the minimum number of elements needed, and for as short an amount of time as reasonably possible. But it’s also good to be as specific as possible. For example, if you’re using &lt;code&gt;will-change&lt;/code&gt; to optimize an animation with the &lt;code&gt;rotate&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt; properties, you should declare this using &lt;code&gt;will-change: rotate, filter&lt;/code&gt;. This is slightly better than using &lt;code&gt;will-change: transform, filter&lt;/code&gt; in a case where you’re animating &lt;code&gt;rotate&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt;, because some of the data structures that Chrome creates in advance when you use &lt;code&gt;will-change&lt;/code&gt; are different for &lt;code&gt;transform&lt;/code&gt; versus &lt;code&gt;rotate&lt;/code&gt;.&lt;/p&gt;
</content>
    <author>
      <name>Bramus</name>
    </author><author>
      <name>L. David Baron</name>
    </author>
  </entry>
  
  <entry>
    <title>CSS border animations</title>
    <link href="https://web.dev/css-border-animations/"/>
    <updated>2022-08-01T00:00:00Z</updated>
    <id>https://web.dev/css-border-animations/</id>
    <content type="html" mode="escaped">&lt;h2 id=&quot;setting-borders&quot;&gt;Setting borders &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-border-animations/#setting-borders&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are a few methods available to set a border on an element: &lt;code&gt;border&lt;/code&gt;, &lt;code&gt;outline&lt;/code&gt;, and &lt;code&gt;box-shadow&lt;/code&gt;. As detailed in &lt;a href=&quot;https://moderncss.dev/the-3-css-methods-for-adding-element-borders/&quot; rel=&quot;noopener&quot;&gt;The 3 CSS Methods for Adding Element Borders&lt;/a&gt; by Stephanie Eckles, each approach comes with its own advantages and disadvantages–especially when it comes to animating the borders. The main reason to not use a proper CSS &lt;code&gt;border&lt;/code&gt; is for animation purposes.&lt;/p&gt;
&lt;figure&gt;
  &lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 585px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/kevinpowell/embed/LYRBxQQ?height=585&amp;theme-id=light&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen LYRBxQQ by kevinpowell on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/kevinpowell/embed/LYRBxQQ&quot;&gt;Pen LYRBxQQ by kevinpowell on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
  &lt;figcaption&gt;Border Animations using &lt;code&gt;outline-offset&lt;/code&gt; by Kevin J. Powell&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;An article that recently caught my attention is &lt;a href=&quot;https://dev.to/chokcoco/fantastic-css-border-animation-5166&quot; rel=&quot;noopener&quot;&gt;Fantastic CSS border animation&lt;/a&gt;, where author Coco explored more options. By injecting &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/CSS_Generated_Content&quot; rel=&quot;noopener&quot;&gt;generated content&lt;/a&gt; using &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt; they create a faux border which is then animated.&lt;/p&gt;
&lt;p&gt;What stands out the most to me are the supporting animated visualizations used in the article. They really help explain what exactly is being done to achieve the desired effect.&lt;/p&gt;
&lt;figure&gt;
&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 485px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/Chokcoco/embed/YzGdEMZ?height=485&amp;theme-id=light&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen YzGdEMZ by Chokcoco on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/Chokcoco/embed/YzGdEMZ&quot;&gt;Pen YzGdEMZ by Chokcoco on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
  &lt;figcaption&gt;Border Animations using generated content by Coco&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Both the white layer and colored lines are generated content. By fading the white layer in and out, it becomes clear how they stack and how the animation works.&lt;/p&gt;
&lt;h2 id=&quot;retaining-the-box-model&quot;&gt;Retaining the box model &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-border-animations/#retaining-the-box-model&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A disadvantage of using Generated Content to imitate a border is that you end up with a broken &lt;a href=&quot;https://developer.mozilla.org/docs/Learn/CSS/Building_blocks/The_box_model&quot; rel=&quot;noopener&quot;&gt;box model&lt;/a&gt;: the content can now obscure the faux border because said “border” is painted underneath. To mitigate, you have to apply the desired &lt;code&gt;border-width&lt;/code&gt; as the &lt;code&gt;padding&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To have a true border–and thus retain the workings of the box model–you can use &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/CSS_Backgrounds_and_Borders/Using_multiple_backgrounds&quot; rel=&quot;noopener&quot;&gt;multiple backgrounds&lt;/a&gt; which you then stretch out into the border area.&lt;/p&gt;
&lt;h3 id=&quot;the-basics&quot;&gt;The basics &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-border-animations/#the-basics&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Let’s start by creating a dotted border and adding the multiple backgrounds.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* Size of the border */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token property&quot;&gt;--border-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0.5rem&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;/* Create a dotted border */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--border-size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; dotted lime&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;/* Create two background layers:&lt;br /&gt;   1. A white semi-transparent&lt;br /&gt;   2. A layer with the colored boxes&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token property&quot;&gt;background-image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;linear-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;to right&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rgb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255 255 255 / 0.5&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rgb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255 255 255 / 0.5&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;conic-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br /&gt;    from 45deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    #d53e33 0deg 90deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    #fbb300 90deg 180deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    #377af5 180deg 270deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    #399953 270deg 360deg&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 485px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/web-dot-dev/embed/dymZzyZ?height=485&amp;theme-id=light&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen dymZzyZ by web-dot-dev on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/web-dot-dev/embed/dymZzyZ&quot;&gt;Pen dymZzyZ by web-dot-dev on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;h3 id=&quot;sizing-the-backgrounds-with-background-origin&quot;&gt;Sizing the backgrounds with &lt;code&gt;background-origin&lt;/code&gt; &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-border-animations/#sizing-the-backgrounds-with-background-origin&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As you can see there is something funny going on with the backgrounds here: they are painted into the border, but the &lt;code&gt;conic-gradient&lt;/code&gt; seems to be all wrong. This is actually intended behavior: by default background images do not draw into the border as their origin is the &lt;code&gt;padding-box&lt;/code&gt; of the element. To create a border after all, the set background images are repeated in the border itself, yielding the weird visual effect.&lt;/p&gt;
&lt;p&gt;To solve this problem, you need to stretch out the background so it also occupies the size of the border. You could do this manually by stretching and repositioning the background, but best is to use the &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/background-origin&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;background-origin&lt;/code&gt;&lt;/a&gt; property to size the background against the &lt;code&gt;border-box&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 1, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      1
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 4, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      4
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 12, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      12
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 3, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      3
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/CSS/background-origin#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;figure class=&quot;compare flow&quot; data-type=&quot;worse&quot; data-size=&quot;full&quot;&gt;&lt;p class=&quot;compare__label&quot;&gt;Don&#39;t&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* Manually add or offset the size of the border where needed */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token property&quot;&gt;background-position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--border-size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * -1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--border-size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * -1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token property&quot;&gt;background-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--border-size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * 2 + 100%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--border-size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; * 2 + 100%&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;figure class=&quot;compare flow&quot; data-type=&quot;better&quot; data-size=&quot;full&quot;&gt;&lt;p class=&quot;compare__label&quot;&gt;Do&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;background-origin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; border-box&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;This one addition makes everything look much better:&lt;/p&gt;
&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 485px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/web-dot-dev/embed/MWVOvYa?height=485&amp;theme-id=light&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen MWVOvYa by web-dot-dev on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/web-dot-dev/embed/MWVOvYa&quot;&gt;Pen MWVOvYa by web-dot-dev on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;h3 id=&quot;shrinking-the-white-background-layer-with-background-clip&quot;&gt;Shrinking the white background layer with &lt;code&gt;background-clip&lt;/code&gt; &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-border-animations/#shrinking-the-white-background-layer-with-background-clip&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;With the backgrounds taking up all the space now, the semi-transparent layer needs to be shrunk down again. Instead of fiddling with &lt;code&gt;background-size&lt;/code&gt; again, there is an easier way to do so: use &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/background-clip&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;background-clip&lt;/code&gt;&lt;/a&gt; and set it to &lt;code&gt;padding-box&lt;/code&gt;. That way the background is no longer drawn underneath the area of the border.&lt;/p&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 1, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      1
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 4, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      4
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 12, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      12
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 5, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      5
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/CSS/background-clip#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;background-clip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;  padding-box&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* Clip white semi-transparent to the padding-box */&lt;/span&gt;&lt;br /&gt;  border-box &lt;span class=&quot;token comment&quot;&gt;/* Clip colored boxes to the border-box (default) */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 785px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/web-dot-dev/embed/JjLOyoJ?height=785&amp;theme-id=light&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen JjLOyoJ by web-dot-dev on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/web-dot-dev/embed/JjLOyoJ&quot;&gt;Pen JjLOyoJ by web-dot-dev on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;Finally, make the border &lt;code&gt;transparent&lt;/code&gt; to have the full effect.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0.3rem dotted transparent&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 485px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/web-dot-dev/embed/mdxqMyj?height=485&amp;theme-id=light&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen mdxqMyj by web-dot-dev on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/web-dot-dev/embed/mdxqMyj&quot;&gt;Pen mdxqMyj by web-dot-dev on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;h3 id=&quot;animation&quot;&gt;Animation &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-border-animations/#animation&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To restore animation of the border, you can manipulate the start angle of the &lt;code&gt;conic-gradient&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;--angle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;conic-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br /&gt;  from &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  #d53e33 0deg 90deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  #fbb300 90deg 180deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  #377af5 180deg 270deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  #399953 270deg 360deg&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Thanks to &lt;a href=&quot;https://web.dev/at-property&quot;&gt;@property&lt;/a&gt; this becomes a breeze in browsers that support it:&lt;/p&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 85, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      85
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox, Not supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;no&quot; title=&quot;Not supported&quot; aria-label=&quot;Not supported&quot;&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;
&lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
&lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
&lt;span class=&quot;visually-hidden&quot;&gt;Edge 85, Supported&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
85
&lt;/span&gt;
&lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
&lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
&lt;span class=&quot;visually-hidden&quot;&gt;Safari 16.4, Supported&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
16.4
&lt;/span&gt;
&lt;/li&gt;&lt;p&gt;&lt;/p&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/CSS/@property#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@property&lt;/span&gt; --angle&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;syntax&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;angle&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;initial-value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; false&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; rotate&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token property&quot;&gt;--angle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 360deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;All combined, the code becomes this:&lt;/p&gt;
&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 485px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/web-dot-dev/embed/BarmdyM?height=485&amp;theme-id=light&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen BarmdyM by web-dot-dev on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/web-dot-dev/embed/BarmdyM&quot;&gt;Pen BarmdyM by web-dot-dev on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;h2 id=&quot;bonus-content-border-image&quot;&gt;Bonus Content: &lt;code&gt;border-image&lt;/code&gt; &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-border-animations/#bonus-content-border-image&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A &lt;a href=&quot;https://web.dev/conic-gradient-border/&quot;&gt;previously covered&lt;/a&gt; approach to draw a gradient border is to use CSS &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/border-image&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;border-image&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 16, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      16
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox 15, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      15
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Edge 12, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      12
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Safari 6, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      6
    &lt;/span&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/CSS/border-image#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;It allows for more simplified code as you do not need to deal with overlapping backgrounds. Animation can be applied in the same manner as before.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/* Create a border */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0.5rem solid transparent&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;/* Paint an image in the border */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token property&quot;&gt;border-image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;conic-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br /&gt;    from &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    #d53e33 0deg 90deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    #fbb300 90deg 180deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    #377af5 180deg 270deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    #399953 270deg 360deg&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 1&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class=&quot;codepen-embed-wrap&quot; style=&quot;height: 485px; width: 100%&quot;&gt;
&lt;iframe allow=&quot;camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;&quot; loading=&quot;lazy&quot; src=&quot;https://codepen.io/web-dot-dev/embed/oNqoeXo?height=485&amp;theme-id=light&amp;default-tab=result&amp;editable=true&quot; style=&quot;height: 100%; width: 100%; border: 0;&quot; title=&quot;Pen oNqoeXo by web-dot-dev on Codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/web-dot-dev/embed/oNqoeXo&quot;&gt;Pen oNqoeXo by web-dot-dev on Codepen&lt;/a&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;However, you’ll notice a few things no longer work with this approach:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;border-image&lt;/code&gt; does not follow the &lt;code&gt;border-radius&lt;/code&gt;; it will always remain rectangular.&lt;/li&gt;
&lt;li&gt;When setting &lt;code&gt;border-image-slice&lt;/code&gt; to fill, the &lt;code&gt;border-image&lt;/code&gt; is not painted underneath the set &lt;code&gt;background&lt;/code&gt; but on top. This can be troublesome if you want the background to be semi-transparent.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;in-closing&quot;&gt;In closing &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/css-border-animations/#in-closing&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There’s a multitude of possibilities to animate borders in CSS. Depending on the use-case, you might lean into one or the other.&lt;/p&gt;
</content>
    <author>
      <name>Bramus</name>
    </author>
  </entry>
</feed>
