<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Coder&#39;s Block</title>
    <link>https://codersblock.com</link>
    <atom:link href="https://codersblock.com/rss.xml" rel="self" type="application/rss+xml" />
    <description>Will Boyd&#39;s portfolio and web development blog.</description>
    <language>en-us</language>
    <lastBuildDate>Fri, 21 Mar 2025 00:00:00 GMT</lastBuildDate>
      
      <item>
        <guid>https://codersblock.com/blog/announcing-wordpress-export-to-markdown-v3/</guid>
        <title>Announcing WordPress Export to Markdown v3</title>
        <link>https://codersblock.com/blog/announcing-wordpress-export-to-markdown-v3/</link>
        <pubDate>Fri, 21 Mar 2025 00:00:00 GMT</pubDate>
        <description>&lt;p&gt;I’m happy to announce the release of &lt;a href=&quot;https://github.com/lonekorean/wordpress-export-to-markdown&quot;&gt;WordPress Export to Markdown&lt;/a&gt; v3! With this milestone, I figured I’d take a moment to share some backstory and talk about the development of this project.&lt;/p&gt;&lt;div class=&quot;post-image-wrapper&quot;&gt;&lt;a href=&quot;https://github.com/lonekorean/wordpress-export-to-markdown&quot;&gt;&lt;img src=&quot;https://codersblock.com/assets/images/blog/wordpress-export-to-markdown-v3-terminal.png&quot; alt=&quot;WordPress Export to Markdown v3 running in a terminal&quot; width=&quot;1000&quot; height=&quot;619&quot; loading=&quot;lazy&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;h2 id=&quot;what-is-it&quot;&gt;&lt;a href=&quot;#what-is-it&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;What Is It?&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;WordPress Export to Markdown is a CLI tool (a Node script) that helps you migrate from WordPress to a static site generator (like &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;Eleventy&lt;/a&gt;, for example). It does this by converting your WordPress export file into Markdown files, as well as downloading and saving all your images.&lt;/p&gt;&lt;p&gt;The end results is all of your site content, collected and formatted to begin a new life as a static site.&lt;/p&gt;&lt;p&gt;A key feature is the user-friendly wizard that guides you through the process, asking you questions about the output you want. There are command line arguments for more advanced options, if you really want to fine-tune things.&lt;/p&gt;&lt;h2 id=&quot;new-in-v3&quot;&gt;&lt;a href=&quot;#new-in-v3&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;New in v3&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The v3 release streamlines the wizard and makes it more intuitive. Some questions were combined into multiple choice questions. Questions that affect filenames and folder structures will now show you an example path for each option, so you can see exactly what the result will be.&lt;/p&gt;&lt;p&gt;Advanced options are easier to use. Previously, you had to edit a &lt;code&gt;settings.js&lt;/code&gt; file, which never felt great to me. Now everything can be set via command line arguments.&lt;/p&gt;&lt;p&gt;Draft posts are now saved. This was a long-standing feature request and I’m glad to finally get it in.&lt;/p&gt;&lt;p&gt;And of course, lots of bug fixes, refactoring, and quality of life improvements. Check the &lt;a href=&quot;https://github.com/lonekorean/wordpress-export-to-markdown/releases/tag/v3.0.0&quot;&gt;full release notes&lt;/a&gt; for more details.&lt;/p&gt;&lt;h2 id=&quot;sharing-it-with-the-world&quot;&gt;&lt;a href=&quot;#sharing-it-with-the-world&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Sharing It with the World&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I first started working on this thing way back in 2018, in preparation for &lt;a href=&quot;https://codersblock.com/blog/coders-block-v6-with-gatsbyjs/&quot;&gt;migrating this very blog&lt;/a&gt; from WordPress to GatsbyJS. I thought others might find it useful, so I open-sourced it.&lt;/p&gt;&lt;p&gt;Since then, the project has been starred over 1,200 times and forked over 240 times on GitHub.&lt;/p&gt;&lt;p&gt;WordPress Export to Markdown has been recommended in the official documentation for &lt;a href=&quot;https://www.11ty.dev/docs/migrate/wordpress/#alternatively-use-a-word-press-export-file&quot;&gt;Eleventy&lt;/a&gt;, &lt;a href=&quot;https://docs.astro.build/en/guides/migrate-to-astro/from-wordpress/#switch-from-wordpress-to-astro&quot;&gt;Astro&lt;/a&gt;, and &lt;a href=&quot;https://tina.io/docs/guides/converting-wordpress-to-tina#getting-started&quot;&gt;TinaCMS&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;It’s also been mentioned in a ton of blog posts by folks writing about migrating from WordPress to their static site generator of choice.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;“So long story short: wordpress-export-to-markdown is a phenomenal tool that I’d highly recommend to anybody looking to export WordPress content as Markdown.” – &lt;a href=&quot;https://joshcollinsworth.com/blog/goodbye-wordpress&quot;&gt;Josh Collinsworth&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;“Learning about this script made the process SO MUCH EASIER because I didn’t have to manually convert each post 💃🏼” – &lt;a href=&quot;https://www.itsthatlady.dev/blog/migrate-from-wordpress-to-astro/&quot;&gt;Kedasha Kerr&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;“This project made my migration an absolute breeze. Not only did it take a standard WordPress export, but it does a damn amazing job at reformatting everything in markdown… lonekorean my dude, I love you.” – &lt;a href=&quot;https://blog.muffn.io/posts/how-i-migrated-from-wordpress-to-hugo/&quot;&gt;Muffn&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h2 id=&quot;next-steps&quot;&gt;&lt;a href=&quot;#next-steps&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Next Steps&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;So what’s next? Well, I tend to work on this project in waves, as my time and mental energy allows. There are still some feature requests on the list I’ll probably get to eventually. I do have one big idea, but it might be a while before I get to it. We’ll see!&lt;/p&gt;</description>
      </item>
      
      <item>
        <guid>https://codersblock.com/blog/making-orbit-animations-with-css-custom-properties/</guid>
        <title>Making Orbit Animations with CSS Custom Properties</title>
        <link>https://codersblock.com/blog/making-orbit-animations-with-css-custom-properties/</link>
        <pubDate>Mon, 16 Sep 2024 00:00:00 GMT</pubDate>
        <description>&lt;p&gt;Let’s animate some CSS custom properties! This is a powerful way to approach CSS animations that would otherwise be tedious or impractical to implement.&lt;/p&gt;&lt;h2 id=&quot;animate-the-what-now&quot;&gt;&lt;a href=&quot;#animate-the-what-now&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Animate the What Now?&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I’ll explain. Take this simple CSS animation, for example.&lt;/p&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; slide-top&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;from&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; -100px&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 selector&quot;&gt;to&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; 100px&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;span class=&quot;token selector&quot;&gt;.top-potato&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; slide-top 3s infinite alternate&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;p&gt;It moves something from left to right, then back, over and over. It works just fine, but we can rewrite it to use a CSS custom property instead.&lt;/p&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; --x&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;&#39;&amp;lt;length&amp;gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; true&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&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; 0px&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 atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; slide-bottom&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;--x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; -100px&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 selector&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;--x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 100px&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;span class=&quot;token selector&quot;&gt;.bottom-potato&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; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--x&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 property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; slide-bottom 3s infinite alternate&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;p&gt;The first thing we do is register an &lt;code&gt;--x&lt;/code&gt; custom property using &lt;code&gt;@property&lt;/code&gt;. This is important, since it enables the value of &lt;code&gt;--x&lt;/code&gt; to be animated. Then instead of animating &lt;code&gt;translate&lt;/code&gt; directly, we animate &lt;code&gt;--x&lt;/code&gt; and set &lt;code&gt;translate&lt;/code&gt; to &lt;code&gt;var(--x)&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;And here are the results, with the “classic” approach on top and the CSS custom property approach on bottom.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;400&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;KKjLbRw&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/KKjLbRw&quot;&gt;Simple Custom Property Animation&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;You might be wondering why we went through all that trouble just to end up with the same animation. Fair point! This was just a basic example to show the concept and syntax.&lt;/p&gt;&lt;p&gt;From this point on, we’ll work through a series of increasingly interesting orbit animations and see how CSS custom properties help us craft them.&lt;/p&gt;&lt;h2 id=&quot;simple-orbit-animation&quot;&gt;&lt;a href=&quot;#simple-orbit-animation&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Simple Orbit Animation&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Here’s a demo of a moon orbiting around a planet while staying upright. Take a look, then we’ll go through the CSS.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;480&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;yLdWGjY&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 480px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/yLdWGjY&quot;&gt;Simple Orbit Animation&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;At the heart of this animation is a custom property named &lt;code&gt;--angle&lt;/code&gt; that goes full circle from &lt;code&gt;0deg&lt;/code&gt; to &lt;code&gt;360deg&lt;/code&gt;. Since these are angle values, we need to make sure we register the custom property as an &lt;code&gt;&amp;lt;angle&amp;gt;&lt;/code&gt;.&lt;/p&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;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;&#39;&amp;lt;angle&amp;gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; true&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&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;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; revolve&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;span class=&quot;token punctuation&quot;&gt;}&lt;/span&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;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;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;p&gt;We can use some basic trigonometry to turn that animated angle value into (x, y) coordinates that follow a perfectly circular path. Don’t worry if you’re not a &lt;a href=&quot;https://en.wiktionary.org/wiki/trigonometrist&quot;&gt;trigonometrist&lt;/a&gt; (real word, believe it or not)! The formula for this is pretty easy.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;x = cos(angle) * amplitude&lt;br&gt;y = sin(angle) * amplitude&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Together, &lt;code&gt;cos()&lt;/code&gt; and &lt;code&gt;sin()&lt;/code&gt; create points along a circle with a radius of &lt;code&gt;1&lt;/code&gt;. That’s pretty small (and unitless) which is where &lt;code&gt;amplitude&lt;/code&gt; comes in — we’ll use it to scale the circle up by some pixel value.&lt;/p&gt;&lt;p&gt;Now that we have the formula, let’s translate it into CSS and add some finishing touches.&lt;/p&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;.moon&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--amplitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 150px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--x&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;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;--amplitude&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;span class=&quot;token property&quot;&gt;--y&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;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;--amplitude&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;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;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--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;--y&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 property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; revolve 12s linear infinite&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;p&gt;It’s the same math discussed above, with &lt;code&gt;--x&lt;/code&gt; and &lt;code&gt;--y&lt;/code&gt; fed into the &lt;code&gt;translate&lt;/code&gt; property to position the orbiting moon. The &lt;code&gt;animation&lt;/code&gt; declaration gets &lt;code&gt;--angle&lt;/code&gt; moving, putting it all in motion.&lt;/p&gt;&lt;p&gt;Note that &lt;code&gt;--angle&lt;/code&gt; was registered via &lt;code&gt;@property&lt;/code&gt; but &lt;code&gt;--x&lt;/code&gt; and &lt;code&gt;--y&lt;/code&gt; were not. They didn’t need to be registered since their values were not being directly animated, just indirectly animated via &lt;code&gt;--angle&lt;/code&gt;.&lt;/p&gt;&lt;h2 id=&quot;elliptical-orbit-animation&quot;&gt;&lt;a href=&quot;#elliptical-orbit-animation&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Elliptical Orbit Animation&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Let’s modify the animation to follow an elliptical path and add a bit of layering.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;400&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;XWLwoqN&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/XWLwoqN&quot;&gt;Elliptical Orbit Animation&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;We’ll keep &lt;code&gt;--angle&lt;/code&gt; from before, but add an animated &lt;code&gt;--z&lt;/code&gt; custom property, which we’ll use to control the &lt;code&gt;z-index&lt;/code&gt; of the moon to make it pass in front of or behind the planet.&lt;/p&gt;&lt;p&gt;We could just animate &lt;code&gt;z-index&lt;/code&gt; directly, but I’m leaning into the animated custom properties approach to show how it works and share a quirk I came across.&lt;/p&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;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;&#39;&amp;lt;angle&amp;gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; true&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&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;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@property&lt;/span&gt; --z&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;&#39;&amp;lt;integer&amp;gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; true&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&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; 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 atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; revolve&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;span class=&quot;token property&quot;&gt;--z&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;span class=&quot;token selector&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;span class=&quot;token property&quot;&gt;--z&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;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;--z&lt;/code&gt; is registered as an &lt;code&gt;&amp;lt;integer&amp;gt;&lt;/code&gt; and animated from &lt;code&gt;-1&lt;/code&gt; (behind the planet) to &lt;code&gt;0&lt;/code&gt; (in front of the planet). Integers in CSS are animated in whole number steps, meaning there are no intermediate decimal values. The value will flip at the midpoint of the animation, which is perfect since that’s when the moon will be off to the left of the planet.&lt;/p&gt;&lt;p&gt;The elliptical path is accomplished by decreasing the amplitude on the y-axis while keeping the same amplitude on the x-axis. So instead of a single &lt;code&gt;--amplitude&lt;/code&gt;, we’ll have an &lt;code&gt;--x-amplitude&lt;/code&gt; and a &lt;code&gt;--y-amplitude&lt;/code&gt; with different values.&lt;/p&gt;&lt;p&gt;Here are the updated styles for the moon.&lt;/p&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;.moon&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--x-amplitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 150px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--y-amplitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 40px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--x&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;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;--x-amplitude&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;span class=&quot;token property&quot;&gt;--y&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;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;--y-amplitude&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;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;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--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;--y&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 property&quot;&gt;z-index&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;--z&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;span class=&quot;token comment&quot;&gt;/* calc() is for Safari */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; revolve 6s linear infinite&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;p&gt;Note that &lt;code&gt;var(--z)&lt;/code&gt; is wrapped in a &lt;code&gt;calc()&lt;/code&gt;. It shouldn’t be necessary to do that, but it fixes an issue in Safari with &lt;code&gt;z-index&lt;/code&gt; not taking the value. Why? I don’t know.&lt;/p&gt;&lt;h2 id=&quot;multiple-elliptical-orbits-animation&quot;&gt;&lt;a href=&quot;#multiple-elliptical-orbits-animation&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Multiple Elliptical Orbits Animation&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Why stop with just a moon?&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;480&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;xxoNmjr&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 480px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/xxoNmjr&quot;&gt;Multiple Elliptical Orbits Animation&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;This continues to build on things we’ve already figured out. The twist here is that the satellite and potato follow a &lt;em&gt;tilted&lt;/em&gt; elliptical orbit. Here’s the CSS to make that happen.&lt;/p&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;.moon, .satellite, .potato&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--x-amplitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 150px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--y-amplitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 40px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--x&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;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;--x-amplitude&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;span class=&quot;token property&quot;&gt;--y&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;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;--y-amplitude&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;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;rotate&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;--rotation&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;translate&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;--x&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;--y&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;rotate&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;--rotation&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;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;z-index&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;--z&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;span class=&quot;token comment&quot;&gt;/* calc() is for Safari */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; revolve 6s linear infinite&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;p&gt;Mostly familiar stuff in there, but the difference is we’ve replaced &lt;code&gt;translate&lt;/code&gt; with &lt;code&gt;transform&lt;/code&gt; to do a sequence of three transformations.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;rotate&lt;/code&gt; to tilt the orientation of the elliptical path by &lt;code&gt;--rotation&lt;/code&gt; degrees.&lt;/li&gt;&lt;li&gt;&lt;code&gt;translate&lt;/code&gt; to position like before, but now within the rotated orientation.&lt;/li&gt;&lt;li&gt;&lt;code&gt;rotate&lt;/code&gt; again the opposite way to undo image rotation (compare this potato to the potato in the very first demo — its orientation is the same).&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The moon, satellite, and potato each have their own &lt;code&gt;--rotation&lt;/code&gt;. They also have staggered negative &lt;code&gt;animation-delay&lt;/code&gt; values, so they don’t crash into each other.&lt;/p&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;.moon&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--rotation&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 property&quot;&gt;animation-delay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0s&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 selector&quot;&gt;.satellite&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--rotation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 60deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;animation-delay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; -2s&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 selector&quot;&gt;.potato&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--rotation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 120deg&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;animation-delay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; -4s&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;h2 id=&quot;multiple-wobbly-elliptical-orbits-animation&quot;&gt;&lt;a href=&quot;#multiple-wobbly-elliptical-orbits-animation&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Multiple Wobbly Elliptical Orbits Animation&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;One more, just for fun. Let’s make it wobbly.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;480&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;qBzGLYP&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 480px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/qBzGLYP&quot;&gt;Multiple Wobbly Elliptical Orbits Animation&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;The CSS is the same as before, except with an updated formula for &lt;code&gt;--x&lt;/code&gt; and &lt;code&gt;--y&lt;/code&gt;.&lt;/p&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;.moon, .satellite, .potato&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--x-amplitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 150px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--y-amplitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 40px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--wobble-multiplier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--wobble-amplitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 5px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--x&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;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;--x-amplitude&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;--wobble-multiplier&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;--wobble-amplitude&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;span class=&quot;token property&quot;&gt;--y&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;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;--y-amplitude&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;--wobble-multiplier&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;--wobble-amplitude&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;span class=&quot;token comment&quot;&gt;/* and all the other stuff from before */&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I won’t go too deeply into the math, but basically it’s the same orbit formula as before but with another smaller and faster orbit added (literally, with a &lt;code&gt;+&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;You know what’s great about this demo? Thanks to the animated custom property approach, all we needed to do was update the math for a single animation. No HTML changes to add extra elements, no keyframe animations added.&lt;/p&gt;&lt;h2 id=&quot;performance&quot;&gt;&lt;a href=&quot;#performance&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Performance&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Currently, CSS custom property animations are always handled by the main thread, even if they’re used with properties that can be GPU-accelerated (like &lt;code&gt;translate&lt;/code&gt; and &lt;code&gt;transform&lt;/code&gt;). In other words, these animations won’t be quite as smooth. For more details, Bramus has a &lt;a href=&quot;https://www.bram.us/2023/02/01/the-gotcha-with-animating-custom-properties/#gotcha&quot;&gt;good explanation of the issue&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Something I’ve noticed in particular is a visible jankiness when text is animated via CSS custom properties. Take a look at this demo.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;320&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;oNrRJdp&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 320px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/oNrRJdp&quot;&gt;Custom Property Text Animation&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;If you look closely, you can see the word “chunky” is jumping pixel by pixel. It doesn’t have sub-pixel animation. It’s easier to see on a non-retina display.&lt;/p&gt;&lt;p&gt;However, I’ve found that using &lt;code&gt;will-change&lt;/code&gt; can smooth things out a bit (in Chrome and Safari at least, unfortunately not in Firefox). This is what I’m using to make the word “smooth” less jittery.&lt;/p&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;.smooth&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;will-change&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; translate&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;p&gt;The animation is still running on the main thread, but at least we get sub-pixel animation to make it smoother.&lt;/p&gt;&lt;h2 id=&quot;until-next-time&quot;&gt;&lt;a href=&quot;#until-next-time&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Until Next Time&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Using CSS custom properties for animation is incredibly useful because it allows us to compose animations in a sensible way. We’re able to pass animated values through a bit of math to create custom animations, without resorting to tedious keyframing or nesting multiple animated elements.&lt;/p&gt;&lt;p&gt;Anyway, hope you had fun making orbital potatoes with me.&lt;/p&gt;</description>
      </item>
      
      <item>
        <guid>https://codersblock.com/blog/anchor-links-and-how-to-make-them-awesome/</guid>
        <title>Anchor Links and How to Make Them Awesome</title>
        <link>https://codersblock.com/blog/anchor-links-and-how-to-make-them-awesome/</link>
        <pubDate>Mon, 20 May 2024 00:00:00 GMT</pubDate>
        <description>&lt;p&gt;Anchor links (also called jump links) are an easy way to provide in-page navigation. For example, a table of contents could use anchor links to take readers straight to various sections in a page.&lt;/p&gt;&lt;p&gt;They’re super easy to set up, but sprinkle a little CSS on top and you can really make them shine. Let’s start with the basics and build from there.&lt;/p&gt;&lt;div class=&quot;post-image-wrapper&quot;&gt;&lt;img src=&quot;https://codersblock.com/assets/images/blog/anchor-rope-map.jpg&quot; alt=&quot;Small anchor pin, resting on rope, on top of a map&quot; width=&quot;800&quot; height=&quot;440&quot; loading=&quot;lazy&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;a-humble-anchor-link&quot;&gt;&lt;a href=&quot;#a-humble-anchor-link&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;A Humble Anchor Link&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To create a page anchor, give an element an &lt;code&gt;id&lt;/code&gt;. That’s it. You can use all sorts of elements as page anchors, though it’s pretty common to use headings.&lt;/p&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;my-anchor&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Page anchor&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now you can link to the page anchor by using &lt;code&gt;#&lt;/code&gt; with the &lt;code&gt;id&lt;/code&gt; as an &lt;code&gt;href&lt;/code&gt;.&lt;/p&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;#my-anchor&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Jump to the page anchor&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There are two special values you can use as the &lt;code&gt;href&lt;/code&gt; of an anchor link: &lt;code&gt;#top&lt;/code&gt; or simply &lt;code&gt;#&lt;/code&gt;. They both do the same thing, taking you to the very top of the page. No need to create a page anchor for these.&lt;/p&gt;&lt;p&gt;Let’s see these anchor links in action.&lt;/p&gt;&lt;blockquote class=&quot;post-demo-link&quot;&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;svg aria-hidden=&quot;true&quot; class=&quot;post-demo-link-arrow&quot;&gt;&lt;use xlink:href=&quot;#arrow&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;a href=&quot;https://codersblock.com/assets/demos/anchor-links/basic.html&quot; target=&quot;_blank&quot;&gt;Anchor Link: Basic&lt;/a&gt;&lt;/blockquote&gt;&lt;p&gt;Notice in the demo how clicking an anchor link adds a hash (like &lt;code&gt;#my-anchor&lt;/code&gt;) to the page’s URL in the address bar — which can be copied and used to link directly to a page anchor, &lt;a href=&quot;https://codersblock.com/assets/demos/anchor-links/basic.html#my-anchor&quot; target=&quot;_blank&quot;&gt;like this&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Now let’s see what adding a little CSS can do.&lt;/p&gt;&lt;h2 id=&quot;adding-smooth-scrolling&quot;&gt;&lt;a href=&quot;#adding-smooth-scrolling&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Adding Smooth Scrolling&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In the previous demo, the jump to the page anchor is instant, which can be a little disorienting. Fortunately, we can enable smooth scrolling with just CSS.&lt;/p&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;html&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;scroll-behavior&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; smooth&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;p&gt;Now give those anchor links another go.&lt;/p&gt;&lt;blockquote class=&quot;post-demo-link&quot;&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;svg aria-hidden=&quot;true&quot; class=&quot;post-demo-link-arrow&quot;&gt;&lt;use xlink:href=&quot;#arrow&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;a href=&quot;https://codersblock.com/assets/demos/anchor-links/smooth.html&quot; target=&quot;_blank&quot;&gt;Anchor Link: Smooth&lt;/a&gt;&lt;/blockquote&gt;&lt;h2 id=&quot;adding-scroll-margin&quot;&gt;&lt;a href=&quot;#adding-scroll-margin&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Adding Scroll Margin&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Our anchor links so far have scrolled the page anchor to the very top edge of the viewport. Wouldn’t it be nice if there was a little breathing room there? We can make that happen by setting &lt;code&gt;scroll-margin-top&lt;/code&gt; on the page anchor.&lt;/p&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;h1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;scroll-margin-top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 40px&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;p&gt;This will leave &lt;code&gt;40px&lt;/code&gt; of space between the top of the viewport and the page anchor. Check it out.&lt;/p&gt;&lt;blockquote class=&quot;post-demo-link&quot;&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;svg aria-hidden=&quot;true&quot; class=&quot;post-demo-link-arrow&quot;&gt;&lt;use xlink:href=&quot;#arrow&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;a href=&quot;https://codersblock.com/assets/demos/anchor-links/smooth-and-margin.html&quot; target=&quot;_blank&quot;&gt;Anchor Link: Smooth + Margin&lt;/a&gt;&lt;/blockquote&gt;&lt;p&gt;This trick is super useful when you have a sticky header, to push page anchors down a bit so they aren’t positioned behind it.&lt;/p&gt;&lt;h2 id=&quot;adding-targeted-page-anchor-styles&quot;&gt;&lt;a href=&quot;#adding-targeted-page-anchor-styles&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Adding Targeted Page Anchor Styles&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;You can use the CSS &lt;code&gt;:target&lt;/code&gt; pseudo-class to add styling to a page anchor when jumping to it.&lt;/p&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;h1:target&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; #71a819&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* green */&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this demo, clicking “Jump to the page anchor” enables the CSS above, making the page anchor text green. Clicking “Jump back to top” causes the &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; to no longer be targeted, so the text will no longer be green.&lt;/p&gt;&lt;blockquote class=&quot;post-demo-link&quot;&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;svg aria-hidden=&quot;true&quot; class=&quot;post-demo-link-arrow&quot;&gt;&lt;use xlink:href=&quot;#arrow&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;a href=&quot;https://codersblock.com/assets/demos/anchor-links/smooth-and-margin-and-styling.html&quot; target=&quot;_blank&quot;&gt;Anchor Link: Smooth + Margin + Styling&lt;/a&gt;&lt;/blockquote&gt;&lt;h2 id=&quot;fancier-target-styling&quot;&gt;&lt;a href=&quot;#fancier-target-styling&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Fancier Target Styling&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We can do more complex things with &lt;code&gt;:target&lt;/code&gt; than just changing text color. Here’s a demo that highlights areas of content and animates a “Back to top” link into view.&lt;/p&gt;&lt;blockquote class=&quot;post-demo-link&quot;&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;svg aria-hidden=&quot;true&quot; class=&quot;post-demo-link-arrow&quot;&gt;&lt;use xlink:href=&quot;#arrow&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;a href=&quot;https://codersblock.com/assets/demos/anchor-links/fancier-styling.html&quot; target=&quot;_blank&quot;&gt;Anchor Link: Fancier Styling&lt;/a&gt;&lt;/blockquote&gt;&lt;p&gt;Here’s the (abbreviated) HTML to show how things are set up.&lt;/p&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;nav&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;#kiwis&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Kiwis&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;#limes&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Limes&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;#pears&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Pears&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;nav&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;article&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;kiwis&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Kiwis&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- blurb about kiwis --&amp;gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;article&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- more article elements here --&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;back-to-top&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;#top&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Back to top&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The article highlighting is accomplished with this CSS.&lt;/p&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;/* border is initially transparent */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;article&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 3px solid transparent&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;/* border turns green for an article when the targeted h1 is within */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;article:has(h1:target)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; #71a819&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;p&gt;And here’s the CSS to show/hide the “Back to top” link.&lt;/p&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;.back-to-top&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* position link to be fixed in top right corner */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fixed&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;/* link is initially faded out and shifted off right edge of viewport */&lt;/span&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&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; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;100% + 10px&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;/* half a second transition duration */&lt;/span&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 0.5s&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;/* when body has a targeted h1 within, fade link in and shift into view */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;body:has(h1:target) .back-to-top&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;span class=&quot;token property&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0px&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;h2 id=&quot;nested-scrolling&quot;&gt;&lt;a href=&quot;#nested-scrolling&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Nested Scrolling&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;All the examples so far had a single scroll container: the page itself. However, it’s possible to have nested scroll containers — for example, a scrollable &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; in the page. If you put a page anchor within a nested scroll container, anchor links pointing to it will scroll all necessary containers to bring the target into view. Neat!&lt;/p&gt;&lt;p&gt;Here’s a demo. Note that the scroll positions feel a bit off — &lt;code&gt;scroll-margin&lt;/code&gt; hasn’t been added. We’ll talk about why next.&lt;/p&gt;&lt;blockquote class=&quot;post-demo-link&quot;&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;svg aria-hidden=&quot;true&quot; class=&quot;post-demo-link-arrow&quot;&gt;&lt;use xlink:href=&quot;#arrow&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;a href=&quot;https://codersblock.com/assets/demos/anchor-links/nested-scroll-without-padding.html&quot; target=&quot;_blank&quot;&gt;Nested Scroll Anchor Link: Without Padding&lt;/a&gt;&lt;/blockquote&gt;&lt;h2 id=&quot;scroll-margin-vs-scroll-padding&quot;&gt;&lt;a href=&quot;#scroll-margin-vs-scroll-padding&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Scroll Margin vs. Scroll Padding&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Now let’s fix those scroll positions. We’ve used &lt;code&gt;scroll-margin-top&lt;/code&gt; before, but in Chrome and Edge, it won’t work here. The scroll margin won’t extend outside of the nested scroll container.&lt;/p&gt;&lt;p&gt;Fortunately, there’s another way to handle this. Instead of &lt;code&gt;scroll-margin&lt;/code&gt;, we can use &lt;code&gt;scroll-padding&lt;/code&gt;. They both give similar results, but the difference is:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;scroll-margin&lt;/code&gt; is used on the page anchor.&lt;/li&gt;&lt;li&gt;&lt;code&gt;scroll-padding&lt;/code&gt; is used on the scroll container.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Let’s update that demo with some &lt;code&gt;scroll-padding&lt;/code&gt;.&lt;/p&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;html&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;scroll-padding-top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 130px&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 selector&quot;&gt;.slide-container&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;scroll-padding-inline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20px&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;p&gt;This adds some generous top scroll padding to the page so the buttons stay in view. It also adds some inline (left and right) scroll padding to the scrollable &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; so each slide is nicely centered in the scroll container.&lt;/p&gt;&lt;blockquote class=&quot;post-demo-link&quot;&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;svg aria-hidden=&quot;true&quot; class=&quot;post-demo-link-arrow&quot;&gt;&lt;use xlink:href=&quot;#arrow&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;a href=&quot;https://codersblock.com/assets/demos/anchor-links/nested-scroll-with-padding.html&quot; target=&quot;_blank&quot;&gt;Nested Scroll Anchor Link: With Padding&lt;/a&gt;&lt;/blockquote&gt;&lt;h2 id=&quot;scroll-into-view-with-javascript&quot;&gt;&lt;a href=&quot;#scroll-into-view-with-javascript&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Scroll Into View with JavaScript&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;You can also use JavaScript to scroll to a page anchor by calling &lt;code&gt;scrollIntoView()&lt;/code&gt;. At its simplest, it looks something like this.&lt;/p&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; anchor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;my-anchor&#39;&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;
anchor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scrollIntoView&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 punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Actually, you don’t even need a page anchor with an &lt;code&gt;id&lt;/code&gt; on it. You can use &lt;code&gt;scrollIntoView()&lt;/code&gt; to scroll to any element.&lt;/p&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; element &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;.whatever&#39;&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;
element&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scrollIntoView&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 punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In either case, the scrolling will be the same as we’ve seen so far, but with some caveats.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The page’s URL in the address bar won’t be updated with a hash.&lt;/li&gt;&lt;li&gt;The element that is scrolled to is not considered targeted, so the CSS &lt;code&gt;:target&lt;/code&gt; pseudo-class won’t work.&lt;/li&gt;&lt;li&gt;In Chrome, Firefox, and Edge, when &lt;code&gt;scrollIntoView()&lt;/code&gt; is used inside an iframe, it can “break out” and also affect the scroll position of the parent page.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If these are showstoppers for you, and you really need to use JavaScript, there is a workaround.&lt;/p&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;location&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;#my-anchor&#39;&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;/code&gt;&lt;/pre&gt;&lt;p&gt;This will behave as if an anchor link to &lt;code&gt;#my-anchor&lt;/code&gt; was clicked.&lt;/p&gt;&lt;h2 id=&quot;scrollintoview-options&quot;&gt;&lt;a href=&quot;#scrollintoview-options&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;ScrollIntoView() Options&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Let’s talk more about &lt;code&gt;scrollIntoView()&lt;/code&gt;. You can fine-tune how it scrolls by providing an (optional) object parameter. Here’s what it looks like with default values.&lt;/p&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;element&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scrollIntoView&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 literal-property property&quot;&gt;behavior&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;auto&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;start&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;inline&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;nearest&#39;&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 punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;behavior&lt;/code&gt; property determines whether scrolling is instant or smooth.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;&#39;auto&#39;&lt;/code&gt; - Uses the value of &lt;code&gt;scroll-behavior&lt;/code&gt; in CSS.&lt;/li&gt;&lt;li&gt;&lt;code&gt;&#39;instant&#39;&lt;/code&gt; - Jumps instantly to the element.&lt;/li&gt;&lt;li&gt;&lt;code&gt;&#39;smooth&#39;&lt;/code&gt; - Scrolls smoothly to the element.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The &lt;code&gt;block&lt;/code&gt; property determines the vertical scroll alignment.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;&#39;start&#39;&lt;/code&gt; - Scrolls the top of the element to the top of the scroll container.&lt;/li&gt;&lt;li&gt;&lt;code&gt;&#39;center&#39;&lt;/code&gt; - Scrolls the center of the element to the center of the scroll container.&lt;/li&gt;&lt;li&gt;&lt;code&gt;&#39;end&#39;&lt;/code&gt; - Scrolls the bottom of the element to the bottom of the scroll container.&lt;/li&gt;&lt;li&gt;&lt;code&gt;&#39;nearest&#39;&lt;/code&gt; - Scrolls just enough to make the element fully visible within the scroll container — or if the element is taller than the scroll container, scrolls just enough so that the element fills the scroll container. If the element is already within or completely filling the scroll container, nothing happens.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The &lt;code&gt;inline&lt;/code&gt; property has similar logic, but for horizontal scroll alignment.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;&#39;start&#39;&lt;/code&gt; - Scrolls the left of the element to the left of the scroll container.&lt;/li&gt;&lt;li&gt;&lt;code&gt;&#39;center&#39;&lt;/code&gt; - Scrolls the center of the element to the center of the scroll container.&lt;/li&gt;&lt;li&gt;&lt;code&gt;&#39;end&#39;&lt;/code&gt; - Scrolls the right of the element to the right of the scroll container.&lt;/li&gt;&lt;li&gt;&lt;code&gt;&#39;nearest&#39;&lt;/code&gt; - Scrolls just enough to make the element fully visible within the scroll container — or if the element is wider than the scroll container, scrolls just enough so that the element fills the scroll container. If the element is already within or completely filling the scroll container, nothing happens.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There can be situations where the scroll alignment you ask for cannot be achieved — usually when an element is at the edge of a scroll container and there’s not enough scroll space to do it. Your browser will still scroll as close as it can.&lt;/p&gt;&lt;p&gt;Alright, that was a lot of words. It’s probably easier to see for yourself, so here’s a scrolling playground to test things out.&lt;/p&gt;&lt;blockquote class=&quot;post-demo-link&quot;&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;svg aria-hidden=&quot;true&quot; class=&quot;post-demo-link-arrow&quot;&gt;&lt;use xlink:href=&quot;#arrow&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;a href=&quot;https://codersblock.com/assets/demos/anchor-links/scroll-into-view-playground.html&quot; target=&quot;_blank&quot;&gt;ScrollIntoView() Playground&lt;/a&gt;&lt;/blockquote&gt;&lt;h2 id=&quot;behind-the-scenes-notes&quot;&gt;&lt;a href=&quot;#behind-the-scenes-notes&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Behind-the-Scenes Notes&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I’ll end with some technical notes from making this article. There were some quirky things I had to deal with that I want to share.&lt;/p&gt;&lt;p&gt;I usually embed Codepen demos right into my articles, using &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;. As you can see, I didn’t do that this time, for two reasons.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Clicked anchor links counts as navigation, which go into your browser’s history. This is true even when those links are inside an &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;. So if you clicked a couple anchor links in embedded demos, then tried to hit the back button on your browser, you’d still be on this blog page.&lt;/li&gt;&lt;li&gt;This was briefly mentioned earlier, but using &lt;code&gt;scrollIntoView()&lt;/code&gt; in an &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; will affect the scroll position of the parent page. There is no sandbox option to fix this. Especially with the last “playground” demo, it was super weird playing with an embedded demo and having the entire page move around. In my testing, Safari was the only browser to not do this.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Another note, when I was researching &lt;code&gt;scroll-margin&lt;/code&gt; and &lt;code&gt;scroll-padding&lt;/code&gt;, I saw a lot of sources that confusingly only talked about their relevance to &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_scroll_snap&quot;&gt;scroll snapping&lt;/a&gt;, to the point that I wondered if using them for page anchors was an unintentional hack. This is not the case, as I discovered that the CSS scroll snap spec itself was &lt;a href=&quot;https://www.w3.org/TR/css-scroll-snap-1/#change-2019-clarify-nonsnapping&quot;&gt;amended to address this confusion specifically&lt;/a&gt;.&lt;/p&gt;</description>
      </item>
      
      <item>
        <guid>https://codersblock.com/blog/playing-with-infinity-in-css/</guid>
        <title>Playing with Infinity in CSS</title>
        <link>https://codersblock.com/blog/playing-with-infinity-in-css/</link>
        <pubDate>Thu, 15 Feb 2024 00:00:00 GMT</pubDate>
        <description>&lt;p&gt;CSS has an &lt;code&gt;infinity&lt;/code&gt; constant. When I first learned about this, my brain lit up with all kinds of absurd possibilities. Let’s discuss! There might even be some practical use cases.&lt;/p&gt;&lt;p&gt;No promises, though.&lt;/p&gt;&lt;div class=&quot;post-image-wrapper&quot;&gt;&lt;img src=&quot;https://codersblock.com/assets/images/blog/infinity-light-streaks.png&quot; alt=&quot;Streaks of light creating the infinity symbol&quot; width=&quot;800&quot; height=&quot;430&quot; loading=&quot;lazy&quot;&gt;&lt;/div&gt;&lt;p&gt;Before we get into things, there’s one important ground rule: &lt;code&gt;infinity&lt;/code&gt; can only be used inside a &lt;code&gt;calc()&lt;/code&gt; statement. Alright, let’s go.&lt;/p&gt;&lt;h2 id=&quot;never-lose-a-z-index-battle-again&quot;&gt;&lt;a href=&quot;#never-lose-a-z-index-battle-again&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Never Lose a z-index Battle Again&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Have you ever needed an element to appear on top of everything else, but the constantly escalating &lt;code&gt;z-index&lt;/code&gt; arms race forces you to resort to higher and higher &lt;code&gt;z-index&lt;/code&gt; values?&lt;/p&gt;&lt;p&gt;End the battle. Use &lt;code&gt;infinity&lt;/code&gt; to get the highest possible &lt;code&gt;z-index&lt;/code&gt; and win forever.&lt;/p&gt;&lt;p&gt;In the demo below, there is no possible &lt;code&gt;z-index&lt;/code&gt; value for the blue card that will put it above the purple card with &lt;code&gt;z-index: calc(infinity)&lt;/code&gt;. Give it a try!&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;400&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;ExMGBVP&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/ExMGBVP&quot;&gt;Unbeatable z-index&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;h2 id=&quot;the-largest-possible-element&quot;&gt;&lt;a href=&quot;#the-largest-possible-element&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;The Largest Possible Element&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;What happens when you create a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; with a &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; of &lt;code&gt;infinity&lt;/code&gt; pixels?&lt;/p&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;.big&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;width&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;infinity * 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 property&quot;&gt;height&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;infinity * 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 punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Notice we’re multiplying &lt;code&gt;infinity&lt;/code&gt; by &lt;code&gt;1px&lt;/code&gt; to turn it into a pixel length.&lt;/p&gt;&lt;p&gt;Here’s a demo showing the result, with some extra output so we can get a better idea of what’s happening in the browser.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;440&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;JjzwQYR&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 440px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/JjzwQYR&quot;&gt;The Largest Possible Element&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;The values under &lt;code&gt;getComputedStyle()&lt;/code&gt; are what the CSS properties resolve to. The values under &lt;code&gt;getBoundingRect()&lt;/code&gt; reflect the actual size of the rendered &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; in the viewport. Here’s the code snippet.&lt;/p&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// getComputedStyle()&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; computed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getComputedStyle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bigEl&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 keyword&quot;&gt;const&lt;/span&gt; computedWidth &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; computed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getPropertyValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;width&#39;&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 keyword&quot;&gt;const&lt;/span&gt; computedHeight &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; computed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getPropertyValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;height&#39;&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 comment&quot;&gt;// getBoundingRect()&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; rect &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; bigEl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBoundingClientRect&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 punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; rectWidth &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;px&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; rectHeight &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;px&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;First of all, &lt;code&gt;infinity&lt;/code&gt; in CSS is not actually infinite. It’s just a really big number. My disappointment is immeasurable, unlike &lt;code&gt;infinity&lt;/code&gt; in CSS.&lt;/p&gt;&lt;p&gt;On my machine (Windows desktop using Chrome) the total area of the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; in the demo is &lt;strong&gt;33,554,428px&lt;/strong&gt; squared, which works out to roughly &lt;strong&gt;79km&lt;sup&gt;2&lt;/sup&gt;&lt;/strong&gt;. Not bad! But also not infinite.&lt;/p&gt;&lt;h2 id=&quot;different-infinities&quot;&gt;&lt;a href=&quot;#different-infinities&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Different Infinities?&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Notice I said “on my machine” in that last paragraph. Although &lt;code&gt;infinity&lt;/code&gt; is supported in all major browsers, the value it resolves to can be inconsistent across browsers and operating systems.&lt;/p&gt;&lt;p&gt;Some examples from the demo above:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Chrome on macOS gives me &lt;strong&gt;16,777,214px&lt;/strong&gt; for both the &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt;, half what I get on Windows.&lt;/li&gt;&lt;li&gt;Firefox reports a &lt;code&gt;width&lt;/code&gt; of &lt;strong&gt;1.78957e+7px&lt;/strong&gt; when using &lt;code&gt;getComputedStyle()&lt;/code&gt; and &lt;strong&gt;8,947,849px&lt;/strong&gt; when using &lt;code&gt;getBoundingRect()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Firefox doesn’t even try with &lt;code&gt;height: calc(infinity * 1px)&lt;/code&gt; — just ignores it. But setting &lt;code&gt;height: 17895697px&lt;/code&gt; (&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=552412#c3&quot;&gt;the largest CSS length Firefox allows&lt;/a&gt;) works. I don’t know why Firefox doesn’t resolve &lt;code&gt;height&lt;/code&gt; to that value like it seems to do with &lt;code&gt;width&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;On top of all that, &lt;code&gt;infinity&lt;/code&gt; can resolve to different values based on which CSS property you’re using it with. Remember that &lt;code&gt;z-index&lt;/code&gt; example from earlier? The value of &lt;code&gt;infinity&lt;/code&gt; there was &lt;strong&gt;2,147,483,647&lt;/strong&gt; — consistent across all browsers I tested, but different from the various &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; values we just saw.&lt;/p&gt;&lt;p&gt;All these wacky values for &lt;code&gt;infinity&lt;/code&gt; are not randomly picked, of course — they are a result of how the numbers are being stored. For example, &lt;strong&gt;2,147,483,647&lt;/strong&gt; is &lt;strong&gt;2&lt;sup&gt;31&lt;/sup&gt; - 1&lt;/strong&gt;, the largest possible value for a signed 32-bit integer.&lt;/p&gt;&lt;h2 id=&quot;animating-to-infinity&quot;&gt;&lt;a href=&quot;#animating-to-infinity&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Animating to Infinity&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;What happens if you try to animate an element to &lt;code&gt;infinity&lt;/code&gt;, like this?&lt;/p&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;.interstellar&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; go 10s&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 atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; go&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;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;infinity * 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 punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Turns out the element will immediately jump to the end of the animation and stay there for the duration. So in this case, the element stays as far off to the right as the browser can handle for the entire 10 seconds.&lt;/p&gt;&lt;p&gt;Makes sense. There are no incremental values on the way to infinity. A fraction of infinity is still infinity. So for every frame of the animation, the animated value is infinity.&lt;/p&gt;&lt;p&gt;What happens when you set an infinite &lt;code&gt;animation-delay&lt;/code&gt;?&lt;/p&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;.interstellar&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;animation-delay&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;infinity * 1s&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;/code&gt;&lt;/pre&gt;&lt;p&gt;You can probably guess. The animation never starts.&lt;/p&gt;&lt;h2 id=&quot;practical-use-cases&quot;&gt;&lt;a href=&quot;#practical-use-cases&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Practical Use Cases&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Would you ever actually want to use &lt;code&gt;infinity&lt;/code&gt; in your CSS? Maybe! Sometimes you just need a huge value (whatever it is) and &lt;code&gt;infinity&lt;/code&gt; can give that to you.&lt;/p&gt;&lt;p&gt;For example, you can make a pill shape by using &lt;code&gt;border-radius&lt;/code&gt; with a (non-percentage) length value. Using a value bigger than you need won’t change the shape and is actually a good idea in case the element changes size.&lt;/p&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&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;border-radius&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;infinity * 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 punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;340&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;LYaMKpx&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 340px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/LYaMKpx&quot;&gt;Pill Shape&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;Another possible use is with a &lt;a href=&quot;https://webaim.org/techniques/css/invisiblecontent/#offscreen&quot;&gt;common snippet of CSS&lt;/a&gt; used to make content “screen reader only” by positioning it way off the side of the page.&lt;/p&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;.screen-reader-only&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;span class=&quot;token property&quot;&gt;left&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;infinity * -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 comment&quot;&gt;/* and some other things */&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But is &lt;code&gt;infinity&lt;/code&gt; really any better than some arbitrarily big value like &lt;code&gt;9999px&lt;/code&gt;? Functionally, no. Same end result. But I think it does help make code more self-documenting, because &lt;code&gt;infinity&lt;/code&gt; conveys intent. It expresses that it’s all about the magnitude, not a specific magic number.&lt;/p&gt;&lt;h2 id=&quot;dividing-by-zero-and-going-negative&quot;&gt;&lt;a href=&quot;#dividing-by-zero-and-going-negative&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Dividing by Zero and Going Negative&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Dividing by zero will give you &lt;code&gt;infinity&lt;/code&gt;. In other words, &lt;code&gt;calc(1 / 0)&lt;/code&gt; and &lt;code&gt;calc(infinity)&lt;/code&gt; are the same. This also works with units. So you can do something like &lt;code&gt;calc(1px / 0)&lt;/code&gt; and get the same value as &lt;code&gt;calc(infinity * 1px)&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Good to know, but I’d still use &lt;code&gt;infinity&lt;/code&gt; directly to make the CSS more obvious.&lt;/p&gt;&lt;p&gt;There’s also a &lt;code&gt;-infinity&lt;/code&gt; constant that gives you the smallest possible value. No surprises here, it’s the same as multiplying &lt;code&gt;infinity&lt;/code&gt; by &lt;code&gt;-1&lt;/code&gt;.&lt;/p&gt;&lt;h2 id=&quot;the-end&quot;&gt;&lt;a href=&quot;#the-end&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;The End&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To recap, the main thing to know about CSS &lt;code&gt;infinity&lt;/code&gt; is that it’s essentially shorthand for the largest possible value in a particular situation. This value can and will change between browsers, operating systems, and CSS properties.&lt;/p&gt;&lt;p&gt;Whether or not to use &lt;code&gt;infinity&lt;/code&gt; is up to you. Browser support is &lt;a href=&quot;https://caniuse.com/mdn-css_types_calc-constant_infinity&quot;&gt;pretty good&lt;/a&gt;, and &lt;code&gt;infinity&lt;/code&gt; can be a good indicator of intention that makes your CSS more readable, but it’s certainly not mandatory.&lt;/p&gt;</description>
      </item>
      
      <item>
        <guid>https://codersblock.com/blog/acronym-frustration/</guid>
        <title>Acronym Frustration</title>
        <link>https://codersblock.com/blog/acronym-frustration/</link>
        <pubDate>Mon, 05 Feb 2024 00:00:00 GMT</pubDate>
        <description>&lt;p&gt;This is me trying to convince you to use acronyms less — or at least be more considerate when you do use them. Let me explain!&lt;/p&gt;&lt;p&gt;And yes, before someone calls me out on it, I am lumping &lt;a href=&quot;https://www.merriam-webster.com/dictionary/initialism&quot;&gt;initialisms&lt;/a&gt; in with acronyms.&lt;/p&gt;&lt;div class=&quot;post-image-wrapper&quot;&gt;&lt;img src=&quot;https://codersblock.com/assets/images/blog/scattered-letters.png&quot; alt=&quot;Scattered pink letters&quot; width=&quot;800&quot; height=&quot;448&quot; loading=&quot;lazy&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;the-frustration&quot;&gt;&lt;a href=&quot;#the-frustration&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;The Frustration&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We use a lot of acronyms. People in just about any industry could say that, but it’s especially true for those of us working in tech. And sure, acronyms are convenient when everyone knows them, but it’s easy to overestimate how often that’s the case.&lt;/p&gt;&lt;p&gt;I’ve been “the new guy” at a company enough times to know how frustrating it is when you’re trying to get up to speed, but everyone is speaking in archaic acronym lingo that obfuscates what they’re talking about.&lt;/p&gt;&lt;p&gt;It’s not just industry standard acronyms — at least you can google these. Acronyms for company-specific or internal-only things are more difficult. I’ve even seen people use acronyms that turned out to be someone’s initials. How could I have possibly known that? I don’t even know that person!&lt;/p&gt;&lt;p&gt;It’s frustrating. It feels like gatekeeping.&lt;/p&gt;&lt;h2 id=&quot;what-to-do&quot;&gt;&lt;a href=&quot;#what-to-do&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;What to Do?&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Obviously you can spell things out instead of using acronyms. That certainly works, but can sometimes be unwieldy.&lt;/p&gt;&lt;p&gt;Another option is to spell out an acronym the first time you use it. This works great for self-contained communication (like emails or docs). For example:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;We’ll be enabling SQM (subscriptions queue manager) on March 2. If you have NOT migrated your apps to SQM yet, please reach out to…&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Something else that can really help is providing an easily accessible “cheat sheet” of acronyms and their definitions. It’s not the perfect solution, since you’re still making people look things up, but it can be incredibly useful when unfamiliar acronyms are inevitably used.&lt;/p&gt;&lt;h2 id=&quot;know-your-audience&quot;&gt;&lt;a href=&quot;#know-your-audience&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Know Your Audience&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I’m not asking for the complete eradication of all acronyms. They have their place. But thinking about who you’re talking to and using acronyms accordingly can be a massive help.&lt;/p&gt;&lt;p&gt;For example, when I’m talking to other web developers, I will absolutely use “CSS”. It would be kind of weird to say “cascading style sheets” every time.&lt;/p&gt;&lt;p&gt;On the other hand, when I’m talking to non-developers, I usually won’t even mention CSS. My team at work has settled on the term “custom styling” instead, which is great — it conveys what is actually being done while sidestepping a tech acronym entirely.&lt;/p&gt;&lt;h2 id=&quot;bonus-ridiculous-acronym&quot;&gt;&lt;a href=&quot;#bonus-ridiculous-acronym&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Bonus: Ridiculous Acronym&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I’ll close this out with my favorite ridiculous acronym, just because of the sheer density of it: XHR. It’s actually an acronym of acronyms that fully expands to “extensible markup language hypertext transfer protocol request”. That’s 56 letters from 3. Not bad!&lt;/p&gt;</description>
      </item>
      
      <item>
        <guid>https://codersblock.com/blog/nicer-text-wrapping-with-css-text-wrap/</guid>
        <title>Nicer Text Wrapping with CSS text-wrap</title>
        <link>https://codersblock.com/blog/nicer-text-wrapping-with-css-text-wrap/</link>
        <pubDate>Sun, 28 Jan 2024 00:00:00 GMT</pubDate>
        <description>&lt;p&gt;Let’s take a look at the CSS &lt;code&gt;text-wrap&lt;/code&gt; property and how we can use it to improve the way text flows on a web page.&lt;/p&gt;&lt;div class=&quot;post-image-wrapper&quot;&gt;&lt;img src=&quot;https://codersblock.com/assets/images/blog/balanced-stones.jpg&quot; alt=&quot;Stones balanced on a desk&quot; width=&quot;800&quot; height=&quot;420&quot; loading=&quot;lazy&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;balanced-text&quot;&gt;&lt;a href=&quot;#balanced-text&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Balanced Text&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We can use &lt;code&gt;text-wrap: balance&lt;/code&gt; to tell the browser to equalize (as much as it can) multiple lines of text. Check out the example below comparing default text wrapping with balanced text wrapping (works in Chrome, Edge, and Firefox).&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;460&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;YzgYwxo&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 460px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/YzgYwxo&quot;&gt;text-wrap: balance (basic)&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;Nice. Manually balancing lines of text with &lt;code&gt;&amp;lt;br&amp;gt;&lt;/code&gt; elements is a hassle and doesn’t fare well with responsive layouts. I’ve also seen JavaScript used to dynamically insert the &lt;code&gt;&amp;lt;br&amp;gt;&lt;/code&gt; elements, but resorting to JavaScript to wrap text is not something I’m excited about. Letting the browser handle it for us with a single line of CSS is much nicer.&lt;/p&gt;&lt;p&gt;Headings are the prime candidate for &lt;code&gt;text-wrap: balance&lt;/code&gt;, especially when they’re centered. Compare these two versions of a heading, unbalanced versus balanced (again, works in Chrome, Edge, and Firefox).&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;460&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;PoLEZJP&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 460px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/PoLEZJP&quot;&gt;text-wrap: balance (heading comparison)&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;Just a note of caution, sometimes applying &lt;code&gt;text-wrap: balance&lt;/code&gt; to left/right aligned headings can make text stack too much to one side, causing your layout to appear lopsided. In other words, ironically, balanced text can unbalance a layout. Use your best judgement!&lt;/p&gt;&lt;h2 id=&quot;pretty-text&quot;&gt;&lt;a href=&quot;#pretty-text&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Pretty Text&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;There’s also &lt;code&gt;text-wrap: pretty&lt;/code&gt;, which tells the browser to use a better but slower algorithm for flowing text. This is intended to be used on body text to improve readability.&lt;/p&gt;&lt;p&gt;Probably the most popular benefit it provides is preventing orphans (an orphan is a word at the end of a paragraph that wraps into a line by itself, which can look a bit awkward). Here’s an example (works in Chrome and Edge).&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;460&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;OJqzMxM&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 460px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/OJqzMxM&quot;&gt;text-wrap: pretty (orphan)&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;Notice how “wanted” would normally be an orphan, but &lt;code&gt;text-wrap: pretty&lt;/code&gt; prevents that. There’s more going on than just wrapping an extra word before the orphan, though. See how “bit” was wrapped to the second line? That’s the algorithm adjusting multiple lines to improve readability. Much better than trying to avoid orphans by “gluing” the last two words of a paragraph together with a &lt;code&gt;&amp;amp;nbsp;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Another benefit of &lt;code&gt;text-wrap: pretty&lt;/code&gt; is reducing excessive hyphenation. Take a look at how it affects text with hyphenation enabled via &lt;code&gt;hyphens: auto&lt;/code&gt; (again, works in Chrome and Edge).&lt;/p&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;p&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;hyphens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; auto&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 selector&quot;&gt;p.bottom&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;text-wrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pretty&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;p class=&quot;codepen&quot; data-height=&quot;460&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;bGZaEow&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 460px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/bGZaEow&quot;&gt;text-wrap: pretty (hyphenation)&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;If, towards the end of a paragraph, there are multiple consecutive lines ending with hyphenated words, then &lt;code&gt;text-wrap: pretty&lt;/code&gt; will adjust them. It’s a nice little readability improvement.&lt;/p&gt;&lt;h2 id=&quot;browser-support&quot;&gt;&lt;a href=&quot;#browser-support&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Browser Support&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;At the time of writing, &lt;code&gt;text-wrap: balance&lt;/code&gt; is not yet supported in Safari, and &lt;code&gt;text-wrap: pretty&lt;/code&gt; is not yet supported in Safari and Firefox. I do expect that full support will come eventually (it’s already in development for Safari).&lt;/p&gt;&lt;p&gt;The great thing though, is you can safely use &lt;code&gt;text-wrap&lt;/code&gt; anyway. Browsers that don’t support it will just ignore it and wrap text normally, so you’re not any worse off.&lt;/p&gt;&lt;h2 id=&quot;performance&quot;&gt;&lt;a href=&quot;#performance&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Performance&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Using &lt;code&gt;text-wrap&lt;/code&gt; with &lt;code&gt;balance&lt;/code&gt; or &lt;code&gt;pretty&lt;/code&gt; invokes layout algorithms that do more work, which can lead to increased rendering time.&lt;/p&gt;&lt;p&gt;For &lt;code&gt;text-wrap: balance&lt;/code&gt;, browsers safeguard against this by only doing the work if the text doesn’t exceed a certain number of lines. Currently, the limit is six lines for Chrome and Edge, and ten lines for Firefox. If the text goes beyond that, &lt;code&gt;text-wrap: balance&lt;/code&gt; is ignored.&lt;/p&gt;&lt;p&gt;There is no such limit for &lt;code&gt;text-wrap: pretty&lt;/code&gt;, which honestly had me slightly concerned. So I tested it.&lt;/p&gt;&lt;p&gt;For my test, I created a &lt;a href=&quot;https://cdpn.io/pen/debug/QWoayqp&quot;&gt;simple page&lt;/a&gt; that repeated a ten-line paragraph 200 times. I made sure the paragraph ended with an orphan for &lt;code&gt;text-wrap: pretty&lt;/code&gt; to fix. Then in the Chrome dev tools performance tab, I enabled 6x CPU slowdown and checked how long it took the page to render — ten times without &lt;code&gt;text-wrap: pretty&lt;/code&gt; and ten times with.&lt;/p&gt;&lt;p&gt;Averaged results:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Without &lt;code&gt;text-wrap: pretty&lt;/code&gt;: 96.7ms&lt;/li&gt;&lt;li&gt;With &lt;code&gt;text-wrap: pretty&lt;/code&gt;: 101.6ms&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Not much of a difference, considering the amount of text and the 6x CPU slowdown. This makes me feel alright about using &lt;code&gt;text-wrap: pretty&lt;/code&gt;. The render times were pretty stable during my testing, so I’m fairly confident in them, but will acknowledge that this wasn’t the most scientifically rigorous experiment.&lt;/p&gt;&lt;h2 id=&quot;in-closing&quot;&gt;&lt;a href=&quot;#in-closing&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;In Closing&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Generally speaking, you’ll want to use &lt;code&gt;text-wrap: balance&lt;/code&gt; for headings and &lt;code&gt;text-wrap: pretty&lt;/code&gt; for body text. Give them a try in your layout and see how they look. If they look good, great! It’s an easy way to improve the overall readability of your web pages. If not, that’s fine, you certainly aren’t required to use them.&lt;/p&gt;&lt;p&gt;If you’re interested in specific situational techniques for controlling text wrapping, check out my &lt;a href=&quot;https://codersblock.com/blog/deep-dive-into-text-wrapping-and-word-breaking/&quot;&gt;deep dive into text wrapping and word breaking&lt;/a&gt;.&lt;/p&gt;</description>
      </item>
      
      <item>
        <guid>https://codersblock.com/blog/writing-is-hard/</guid>
        <title>Writing Is Hard</title>
        <link>https://codersblock.com/blog/writing-is-hard/</link>
        <pubDate>Mon, 01 Jan 2024 00:00:00 GMT</pubDate>
        <description>&lt;p&gt;I didn’t blog a single time in 2023. In fact, I haven’t blogged since &lt;a href=&quot;https://codersblock.com/blog/star-wars-scene-transition-effects-in-css/&quot;&gt;June of 2022&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I kept telling myself “hey, I should write something” but never did, and then enough of the year passed that I decided to just lean into it and make 2023 the year I took a break from writing.&lt;/p&gt;&lt;h2 id=&quot;its-a-slow-process&quot;&gt;&lt;a href=&quot;#its-a-slow-process&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;It’s a Slow Process&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The thing is, writing does not come naturally to me at all. I’m a terribly slow writer. Words don’t flow out of my brain, they just sort of… fall out like a game of Tetris where none of the pieces are stacking well. It’s hard to make them stack well.&lt;/p&gt;&lt;p&gt;So when I’m writing the sorts of long-form deep dive CSS articles that I tend to write, it’s an incredibly laborious process. And that’s just the writing part. There’s also the research, experimentation, coding up the demos, and testing. These types of blog posts typically take me about a month to finish, sometimes longer.&lt;/p&gt;&lt;h2 id=&quot;yeah-burnout&quot;&gt;&lt;a href=&quot;#yeah-burnout&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Yeah, Burnout&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I love web development. It’s amazing that I can have a job doing something I enjoy so much. It’s also my favorite hobby, because, again, I love web development. There have been many times where, after a hard day of web development, I’d find myself relaxing with… more web development.&lt;/p&gt;&lt;p&gt;I’ve created a life for myself where my day job is web development, I run a web development blog, and I have multiple web development side projects. You can see where this is going.&lt;/p&gt;&lt;p&gt;Burnout is inevitable. When it hits, I have to prioritize what I put my energy into. Naturally, I prioritize the thing that pays the bills, putting the rest aside so that burnout doesn’t swallow me whole.&lt;/p&gt;&lt;p&gt;And that’s why I didn’t blog a single time in 2023.&lt;/p&gt;&lt;h2 id=&quot;im-not-done&quot;&gt;&lt;a href=&quot;#im-not-done&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;I’m Not Done&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;This isn’t “goodbye” or anything like that. Just sharing my headspace. I still love web development, in case that wasn’t clear. I want to get back into blogging, but in a way that doesn’t consume too much of me. Maybe I’ll try writing more short-form blog posts.&lt;/p&gt;&lt;p&gt;We’ll see!&lt;/p&gt;</description>
      </item>
      
      <item>
        <guid>https://codersblock.com/blog/star-wars-scene-transition-effects-in-css/</guid>
        <title>Star Wars Scene Transition Effects in CSS</title>
        <link>https://codersblock.com/blog/star-wars-scene-transition-effects-in-css/</link>
        <pubDate>Wed, 01 Jun 2022 00:00:00 GMT</pubDate>
        <description>&lt;p&gt;You know those wipe transitions between scenes in Star Wars movies? Have you ever thought it would be awesome to recreate them with CSS? Probably not, but, well, here we are. Let’s do it.&lt;/p&gt;&lt;p&gt;Spoiler alert: this article is secretly a tutorial on animating CSS masks.&lt;/p&gt;&lt;h2 id=&quot;a-simple-gradient-mask&quot;&gt;&lt;a href=&quot;#a-simple-gradient-mask&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;A Simple Gradient Mask&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;CSS masking allows you to control which pixels of an element are visible and which are transparent — masked, if you will. A mask comes in the form of an image or gradient. When a mask is applied to an element, it acts as a sort of map that determines the visibility of every pixel of the element.&lt;/p&gt;&lt;p&gt;Masking is not always binary. Pixels can be partially masked, resulting in semi-transparent pixels.&lt;/p&gt;&lt;p&gt;As an example, the demo below uses CSS masking to cross-fade two scenes together.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;440&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;PoQemgQ&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 440px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/PoQemgQ&quot;&gt;Simple Gradient Mask&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;The first scene has the Death Star. The second scene has Jyn Erso, and is positioned directly on top of the first scene. A gradient mask is used on the second scene to make its left side transparent, revealing the first scene.&lt;/p&gt;&lt;p&gt;Here’s how it’s set up in the HTML.&lt;/p&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;wrapper&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;scenes&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;scene-1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;scene-2&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And here’s the CSS. It’s mostly positioning and sizing, along with setting the scene images, but pay attention to the &lt;code&gt;-webkit-mask-image&lt;/code&gt; declaration on &lt;code&gt;.scene-2&lt;/code&gt;.&lt;/p&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;.wrapper&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;1000px&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 punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.scenes&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; relative&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&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; 2.4 / 1&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 selector&quot;&gt;.scene-1, .scene-2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;span class=&quot;token property&quot;&gt;inset&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 property&quot;&gt;background-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cover&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 selector&quot;&gt;.scene-1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;scene-1.jpg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&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;span class=&quot;token selector&quot;&gt;.scene-2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;scene-2.jpg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;-webkit-mask-image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&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; transparent 33%&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; #fff 67%&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;/code&gt;&lt;/pre&gt;&lt;p&gt;The mask is set on &lt;code&gt;-webkit-mask-image&lt;/code&gt; and expressed as a &lt;code&gt;linear-gradient()&lt;/code&gt; going from left to right. Let’s dissect it.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The first third is entirely transparent, so this portion of the scene is not visible.&lt;/li&gt;&lt;li&gt;The middle third progresses from transparent to opaque white, gradually fading the scene in.&lt;/li&gt;&lt;li&gt;The last third is entirely opaque white, causing this portion of the scene to be fully visible.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;To sum it up, &lt;strong&gt;transparent pixels hide&lt;/strong&gt; and &lt;strong&gt;opaque pixels show&lt;/strong&gt;. The color doesn’t even matter. I like to use white, but any color will do. It’s all about the opacity.&lt;/p&gt;&lt;p&gt;It’s also worth mentioning that I’m using the vendor prefixed &lt;code&gt;-webkit-mask-image&lt;/code&gt; (supported in all major browsers) but not &lt;code&gt;mask-image&lt;/code&gt; (currently only recognized by Firefox and Safari). I’m doing this for the sake of brevity, but feel free to use them both together if you want.&lt;/p&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;.scene-2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;-webkit-mask-image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&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; transparent 33%&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; #fff 67%&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 property&quot;&gt;mask-image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&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; transparent 33%&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; #fff 67%&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;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;horizontal-wipe-transition&quot;&gt;&lt;a href=&quot;#horizontal-wipe-transition&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Horizontal Wipe Transition&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Let’s build on top of what we’ve covered so far to create our first scene transition effect, a horizontal wipe. Take a look.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;650&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;NWyMjmL&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 650px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/NWyMjmL&quot;&gt;Horizontal Wipe Transition&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;The basic HTML and CSS set up is the same as last time. And once again, the mask is a &lt;code&gt;linear-gradient()&lt;/code&gt; that fades from &lt;code&gt;transparent&lt;/code&gt; to &lt;code&gt;#fff&lt;/code&gt; in the middle.&lt;/p&gt;&lt;p&gt;So how is the fade animated across the scene? The small visualizer underneath gives you a hint. The mask is stretched to be wider than the actual scene, and is then animated to slide horizontally. Here’s the relevant CSS.&lt;/p&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;.scene-2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;scene-2.jpg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;-webkit-mask-image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&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;
    transparent 47.5%&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    #fff 52.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 property&quot;&gt;-webkit-mask-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 210%&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;-webkit-mask-position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; left&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;/* these styles are activated on the .scene-2 element
   when the .scenes element is hovered or focused */&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.scenes:is(:hover, :focus) .scene-2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;-webkit-mask-position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; right&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; -webkit-mask-position 2s linear&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;p&gt;The mask is sized with &lt;code&gt;-webkit-mask-size: 210%&lt;/code&gt; — this provides a width of 100% for the scene to initially be fully transparent + 10% for the fade + another 100% for the scene to end up fully opaque.&lt;/p&gt;&lt;p&gt;To reveal the scene, we &lt;code&gt;transition&lt;/code&gt; the value of &lt;code&gt;-webkit-mask-position&lt;/code&gt; so the mask shifts from &lt;code&gt;left&lt;/code&gt;-aligned to &lt;code&gt;right&lt;/code&gt;-aligned. Note that the &lt;code&gt;background-image&lt;/code&gt; doesn’t move, only the mask does.&lt;/p&gt;&lt;p&gt;CSS masking doesn’t just mask an element’s background, it masks the entire element and everything in it. See that “BB-8 and Rey” text on the second scene? That’s an &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; element within the scene element, also being affected by the mask.&lt;/p&gt;&lt;h2 id=&quot;iris-wipe-transition&quot;&gt;&lt;a href=&quot;#iris-wipe-transition&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Iris Wipe Transition&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Next up is an iris wipe, fading a scene in from the middle out. Heads up, the animation relies on the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CSS_Properties_and_Values_API/guide&quot;&gt;CSS properties and values API&lt;/a&gt;, which is not yet ready in Firefox and Safari, but is expected to come in the future.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;650&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;yLvjbrr&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 650px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/yLvjbrr&quot;&gt;Iris Wipe Transition&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;The basic HTML and CSS are still the same, but this time we’re using a &lt;code&gt;radial-gradient()&lt;/code&gt; as the mask. We’ll need to approach the animation differently, since animating the mask’s position won’t give us the effect we want. This is a job for &lt;strong&gt;CSS custom properties&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;The plan is to define the &lt;code&gt;radial-gradient()&lt;/code&gt; with a custom property in it. Then we can animate that custom property to animate the gradient. But before we can do that, we need to register the custom property with &lt;code&gt;@property&lt;/code&gt;.&lt;/p&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; --radius&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;&#39;&amp;lt;percentage&amp;gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; true&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&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; -5%&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;p&gt;This tells the browser that there’s a custom property named &lt;code&gt;--radius&lt;/code&gt; that holds &lt;code&gt;percentage&lt;/code&gt; values and defaults to a value of &lt;code&gt;-5%&lt;/code&gt;. With that done, we can animate &lt;code&gt;--radius&lt;/code&gt; with a simple keyframes animation.&lt;/p&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; scene-transition&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;span class=&quot;token property&quot;&gt;--radius&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 105%&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;/code&gt;&lt;/pre&gt;&lt;p&gt;Here’s the CSS for &lt;code&gt;.scene-2&lt;/code&gt; to bring it all together.&lt;/p&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;.scene-2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;scene-2.jpg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;z-index&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 property&quot;&gt;-webkit-mask-image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;radial-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    circle&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    #fff &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;--radius&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 punctuation&quot;&gt;,&lt;/span&gt;
    transparent &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;--radius&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 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;span class=&quot;token selector&quot;&gt;.scenes:is(:hover, :focus) .scene-2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;z-index&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 property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; scene-transition 2s linear forwards&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;p&gt;As &lt;code&gt;--radius&lt;/code&gt; animates, so do the color-stop positions in the &lt;code&gt;radial-gradient()&lt;/code&gt;. They are calculated to be &lt;code&gt;-5%&lt;/code&gt; and &lt;code&gt;+5%&lt;/code&gt; of the value of &lt;code&gt;--radius&lt;/code&gt; to create the gradual fade that gives the wipe a soft edge.&lt;/p&gt;&lt;p&gt;The fade is why the value of &lt;code&gt;--radius&lt;/code&gt; goes from &lt;code&gt;-5%&lt;/code&gt; to &lt;code&gt;105%&lt;/code&gt;. We pull back an extra 5% at the start to ensure all pixels are fully hidden, then progress an extra 5% at the end to ensure all pixels are fully visible.&lt;/p&gt;&lt;p&gt;As mentioned earlier, the animation doesn’t work in Firefox and Safari. As a fallback, &lt;code&gt;.scene-2&lt;/code&gt; starts with &lt;code&gt;z-index: -1&lt;/code&gt; to hide it behind the first scene, which is flipped to &lt;code&gt;z-index: 1&lt;/code&gt; to show it on top of the first scene. So at least the scenes will still switch on all browsers.&lt;/p&gt;&lt;h2 id=&quot;clock-wipe-transition&quot;&gt;&lt;a href=&quot;#clock-wipe-transition&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Clock Wipe Transition&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The clock wipe is probably the most iconic wipe transition from Star Wars. Let’s make it. Once again, we’ll be animating a CSS custom property.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;650&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;eYVrWoq&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 650px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/eYVrWoq&quot;&gt;Clock Wipe Transition&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;It uses a lot of the same techniques as the iris wipe, except this time we’re using &lt;code&gt;conic-gradient()&lt;/code&gt; and animating an &lt;code&gt;angle&lt;/code&gt; value.&lt;/p&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;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;&#39;&amp;lt;angle&amp;gt;&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;inherits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; true&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&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; -10deg&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 atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@keyframes&lt;/span&gt; scene-transition&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;span class=&quot;token property&quot;&gt;--angle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 370deg&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;span class=&quot;token selector&quot;&gt;.scene-2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;scene-2.jpg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;z-index&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 property&quot;&gt;-webkit-mask-image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&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;
      #fff 0deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      #fff &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;--angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; - 10deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      transparent &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;--angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; + 10deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      transparent 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 function&quot;&gt;conic-gradient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      transparent 340deg&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      #fff 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;span class=&quot;token selector&quot;&gt;.scenes:is(:hover, :focus) .scene-2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;z-index&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 property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; scene-transition 2s linear forwards&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;p&gt;We’re using two gradients in &lt;code&gt;-webkit-mask-image&lt;/code&gt;. The first &lt;code&gt;conic-gradient()&lt;/code&gt; is animated to create the clock wipe effect, but it leaves a hard edge at its starting point (at &lt;code&gt;0deg&lt;/code&gt;). That’s why there’s a second &lt;code&gt;conic-gradient()&lt;/code&gt; to create a small fade right before the hard edge and soften it out. The gradients combine together to create the mask for the scene.&lt;/p&gt;&lt;h2 id=&quot;shape-zoom-transition&quot;&gt;&lt;a href=&quot;#shape-zoom-transition&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Shape Zoom Transition&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Now for something different. I call this one a “shape zoom” transition. It’s not in any Star Wars movie, but I think it’s a pretty cool effect. It doesn’t animate a CSS custom property, so it works in all major browsers.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;650&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;zYRjwQx&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 650px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/zYRjwQx&quot;&gt;Shape Zoom Transition&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;I’ll just go ahead and spill the CSS for animating &lt;code&gt;.scene-2&lt;/code&gt;, then talk through it.&lt;/p&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; scene-transition&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;25%&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;brightness&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 punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&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;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;brightness&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 punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;-webkit-mask-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1800%&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;span class=&quot;token selector&quot;&gt;.scene-2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&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;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;scene-2.jpg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;brightness&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 property&quot;&gt;-webkit-mask-image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token url&quot;&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;jedi-crest.svg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;-webkit-mask-size&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 property&quot;&gt;-webkit-mask-position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; center&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;-webkit-mask-repeat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; no-repeat&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 selector&quot;&gt;.scenes:is(:hover, :focus) .scene-2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; scene-transition 4s &lt;span class=&quot;token function&quot;&gt;cubic-bezier&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; 0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; forwards&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;p&gt;No gradients this time. Instead, &lt;code&gt;-webkit-mask-image&lt;/code&gt; is given an SVG of the Jedi crest, masking &lt;code&gt;.scene-2&lt;/code&gt; into the shape that you see. The mask is positioned in the &lt;code&gt;center&lt;/code&gt; of the scene and sized to &lt;code&gt;10%&lt;/code&gt;. Adding &lt;code&gt;filter: brightness(0%)&lt;/code&gt; removes all brightness, resulting in the Jedi crest being completely black.&lt;/p&gt;&lt;p&gt;The animation uses an aggressive &lt;code&gt;cubic-bezier()&lt;/code&gt; curve that &lt;a href=&quot;https://cubic-bezier.com/#1,0,1,1&quot;&gt;starts out really slow, then gets really fast&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;code&gt;-webkit-mask-size&lt;/code&gt; is animated from &lt;code&gt;10%&lt;/code&gt; to &lt;code&gt;1800%&lt;/code&gt; so that the narrow bit in the middle of the Jedi crest grows large enough to cover the entire scene, fully revealing Darth Maul.&lt;/p&gt;&lt;p&gt;&lt;code&gt;filter: brightness()&lt;/code&gt; is animated from &lt;code&gt;0%&lt;/code&gt; to &lt;code&gt;100%&lt;/code&gt;, fading the scene from black back to normal. This part of the animation is set to finish at the &lt;code&gt;25%&lt;/code&gt; time mark, before &lt;code&gt;-webkit-mask-size&lt;/code&gt; is done growing.&lt;/p&gt;&lt;h2 id=&quot;until-next-time&quot;&gt;&lt;a href=&quot;#until-next-time&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Until Next Time&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We’ve covered quite a few CSS ingredients in this article, including different types of gradients, registering custom properties, and of course masking and animation.&lt;/p&gt;&lt;p&gt;I used Star Wars scenes as my examples, but my hope is that you can take these techniques and use them to create your own neat visual effects for other things.&lt;/p&gt;&lt;p&gt;Have fun with it. Thanks for reading!&lt;/p&gt;</description>
      </item>
      
      <item>
        <guid>https://codersblock.com/blog/deep-dive-into-text-wrapping-and-word-breaking/</guid>
        <title>Deep Dive into Text Wrapping and Word Breaking</title>
        <link>https://codersblock.com/blog/deep-dive-into-text-wrapping-and-word-breaking/</link>
        <pubDate>Mon, 02 May 2022 00:00:00 GMT</pubDate>
        <description>&lt;p&gt;Let’s talk about the various ways we can control how text wraps (or doesn’t wrap) on a web page. CSS gives us a lot of tools to make sure our text flows the way we want it to, but we’ll also cover some tricks using HTML and special characters.&lt;/p&gt;&lt;div class=&quot;post-image-wrapper&quot;&gt;&lt;img src=&quot;https://codersblock.com/assets/images/blog/wrapped-box.jpg&quot; alt=&quot;Box wrapped with long ribbon&quot; width=&quot;800&quot; height=&quot;406&quot; loading=&quot;lazy&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;protecting-layout&quot;&gt;&lt;a href=&quot;#protecting-layout&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Protecting Layout&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Normally, text flows to the next line at “soft wrap opportunities”, which is a fancy name for spots you’d expect text to break naturally, like between words or after a hyphen. But sometimes you may find yourself with long spans of text that don’t have soft wrap opportunities, such as really long words or URLs. This can cause all sorts of layout issues. For example, the text may overflow its container, or it might force the container to become too wide and push things out of place.&lt;/p&gt;&lt;p&gt;It’s good defensive coding to anticipate issues from text not breaking. Fortunately, CSS gives us some tools for this.&lt;/p&gt;&lt;h2 id=&quot;getting-overflowing-text-to-wrap&quot;&gt;&lt;a href=&quot;#getting-overflowing-text-to-wrap&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Getting Overflowing Text to Wrap&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Putting &lt;code&gt;overflow-wrap: break-word&lt;/code&gt; on an element will allow text to break mid-word if needed. It’ll first try to keep a word unbroken by moving it to the next line, but will then break the word if there’s still not enough room.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;460&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;dydPWvo&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 460px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/dydPWvo&quot;&gt;overflow-wrap: break-word&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;There’s also &lt;code&gt;overflow-wrap: anywhere&lt;/code&gt;, which breaks words in the same manner. The difference is in how it affects the &lt;code&gt;min-content&lt;/code&gt; size calculation of the element it’s on. It’s pretty easy to see when &lt;code&gt;width&lt;/code&gt; is set to &lt;code&gt;min-content&lt;/code&gt;.&lt;/p&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;.top&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; min-content&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;overflow-wrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; break-word&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 selector&quot;&gt;.bottom&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; min-content&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;overflow-wrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; anywhere&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;p class=&quot;codepen&quot; data-height=&quot;460&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;vYdEmxG&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 460px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/vYdEmxG&quot;&gt;overflow-wrap + min-content&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;The top element with &lt;code&gt;overflow-wrap: break-word&lt;/code&gt; calculates &lt;code&gt;min-content&lt;/code&gt; as if no words are broken, so its width becomes the width of the longest word. The bottom element with &lt;code&gt;overflow-wrap: anywhere&lt;/code&gt; calculates &lt;code&gt;min-content&lt;/code&gt; with all the breaks it can create. Since a break can happen, well, anywhere, &lt;code&gt;min-content&lt;/code&gt; ends up being the width of a single character.&lt;/p&gt;&lt;p&gt;Remember, this behavior only comes into play when &lt;code&gt;min-content&lt;/code&gt; is involved. If we had set &lt;code&gt;width&lt;/code&gt; to some rigid value, we’d see the same word-breaking result for both.&lt;/p&gt;&lt;h2 id=&quot;breaking-words-without-mercy&quot;&gt;&lt;a href=&quot;#breaking-words-without-mercy&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Breaking Words without Mercy&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Another option for breaking words is &lt;code&gt;word-break: break-all&lt;/code&gt;. This one won’t even try to keep words whole — it’ll just break them immediately. Take a look.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;460&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;GRQgmWN&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 460px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/GRQgmWN&quot;&gt;word-break: break-all&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;Notice how the long word isn’t moved to the next line, like it would have been when using &lt;code&gt;overflow&lt;/code&gt;. Also notice how “words” is broken, even though it would have fit just fine on the next line.&lt;/p&gt;&lt;p&gt;&lt;code&gt;word-break: break-all&lt;/code&gt; has no problem breaking words, but it’s still cautious around punctuation. For example, it’ll avoid starting a line with the period from the end of a sentence. If you want truly merciless breaking, even with punctuation, use &lt;code&gt;line-break: anywhere&lt;/code&gt;.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;400&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;PoQwmpp&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/PoQwmpp&quot;&gt;word-break: break-all vs line-break: anywhere&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;See how &lt;code&gt;word-break: break-all&lt;/code&gt; moves the “k” down to avoid starting the second line with “.”? Meanwhile, &lt;code&gt;line-break: anywhere&lt;/code&gt; doesn’t care.&lt;/p&gt;&lt;h2 id=&quot;excessive-punctuation&quot;&gt;&lt;a href=&quot;#excessive-punctuation&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Excessive Punctuation&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Let’s see how the CSS properties we’ve covered so far handle excessively long spans of punctuation.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;600&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;OJQPmpm&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 600px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/OJQPmpm&quot;&gt;Excessive Punctuation&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;&lt;code&gt;overflow-wrap: break-word&lt;/code&gt; and &lt;code&gt;line-break: anywhere&lt;/code&gt; are able to keep things contained, but then there’s &lt;code&gt;word-break: break-all&lt;/code&gt; being weird with punctuation again — this time resulting in overflowing text.&lt;/p&gt;&lt;p&gt;It’s something to keep in mind. If you absolutely do not want text to overflow, be aware that &lt;code&gt;word-break: break-all&lt;/code&gt; won’t stop runaway punctuation.&lt;/p&gt;&lt;h2 id=&quot;specifying-where-words-can-break&quot;&gt;&lt;a href=&quot;#specifying-where-words-can-break&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Specifying Where Words Can Break&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;For more control, you can manually insert word break opportunities into your text with &lt;code&gt;&amp;lt;wbr&amp;gt;&lt;/code&gt;. You can also use a “zero-width space”, provided by the &lt;code&gt;&amp;amp;ZeroWidthSpace;&lt;/code&gt; HTML entity (yes, it must be capitalized just as you see it!).&lt;/p&gt;&lt;p&gt;Let’s see these in action by wrapping a long URL that normally wouldn’t wrap, but only between segments.&lt;/p&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- normal --&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;https://subdomain.somewhere.co.uk&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- &amp;lt;wbr&amp;gt; --&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;https://subdomain&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;wbr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;.somewhere&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;wbr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;.co&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;wbr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;.uk&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- &amp;amp;ZeroWidthSpace; --&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;https://subdomain&amp;amp;ZeroWidthSpace;.somewhere&amp;amp;ZeroWidthSpace;.co&amp;amp;ZeroWidthSpace;.uk&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;510&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;wvyBdJq&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 510px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/wvyBdJq&quot;&gt;Manual Word Break Opportunities&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;h2 id=&quot;automatic-hyphenation&quot;&gt;&lt;a href=&quot;#automatic-hyphenation&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Automatic Hyphenation&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;You can tell the browser to break and hyphenate words where appropriate by using &lt;code&gt;hyphens: auto&lt;/code&gt;. Hyphenation rules are determined by language, so you’ll need to tell the browser what language to use. This is done by specifying the &lt;code&gt;lang&lt;/code&gt; attribute in HTML, possibly on the relevant element directly, or on &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;en&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;This is just a bit of arbitrary text to show hyphenation in action.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&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;p&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;-webkit-hyphens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; auto&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/* for Safari */&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;hyphens&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; auto&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;p class=&quot;codepen&quot; data-height=&quot;290&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;NWyPjpw&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 290px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/NWyPjpw&quot;&gt;hyphens: auto&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;h2 id=&quot;manual-hyphenation&quot;&gt;&lt;a href=&quot;#manual-hyphenation&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Manual Hyphenation&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;You can also take matters into your own hands and insert a “soft hyphen” manually with the &lt;code&gt;&amp;amp;shy;&lt;/code&gt; HTML entity. It won’t be visible unless the browser decides to wrap there, in which case a hyphen will appear. Notice in the following demo how we’re using &lt;code&gt;&amp;amp;shy;&lt;/code&gt; twice, but we only see it once where the text wraps.&lt;/p&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;en&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Magic? Abraca&lt;span class=&quot;token entity named-entity&quot; title=&quot;­&quot;&gt;&amp;amp;shy;&lt;/span&gt;dabra? Abraca&lt;span class=&quot;token entity named-entity&quot; title=&quot;­&quot;&gt;&amp;amp;shy;&lt;/span&gt;dabra!&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;260&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;jOZEmBz&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 260px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/jOZEmBz&quot;&gt;Soft Hyphen&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;&lt;code&gt;hyphens&lt;/code&gt; must be set to either &lt;code&gt;auto&lt;/code&gt; or &lt;code&gt;manual&lt;/code&gt; for &lt;code&gt;&amp;amp;shy;&lt;/code&gt; to display properly. Conveniently, the default is &lt;code&gt;hyphens: manual&lt;/code&gt;, so you should be good without any additional CSS (unless something has declared &lt;code&gt;hyphens: none&lt;/code&gt; for some reason).&lt;/p&gt;&lt;h2 id=&quot;preventing-text-from-wrapping&quot;&gt;&lt;a href=&quot;#preventing-text-from-wrapping&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Preventing Text from Wrapping&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Let’s switch things up. There may be times when you don’t want text to wrap freely, so that you have better control over how your content is presented. There are a couple of tools to help you with this.&lt;/p&gt;&lt;p&gt;First up is &lt;code&gt;white-space: nowrap&lt;/code&gt;. Put it on an element to prevent its text from wrapping naturally.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;370&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;qBxEmVE&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 370px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/qBxEmVE&quot;&gt;white-space: nowrap&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;h2 id=&quot;preformatting-text&quot;&gt;&lt;a href=&quot;#preformatting-text&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Preformatting Text&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;There’s also &lt;code&gt;white-space: pre&lt;/code&gt;, which will wrap text just as you have it typed in your HTML. Be careful though, as it will also preserve spaces from your HTML, so be mindful of your formatting. You can also use a &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; tag to get the same results (it has &lt;code&gt;white-space: pre&lt;/code&gt; on it by default).&lt;/p&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- the formatting of this HTML results in extra whitespace! --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  What&#39;s worse, ignorance or apathy?
  I don&#39;t know and I don&#39;t care.
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- tighter formatting that &quot;hugs&quot; the text --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;What&#39;s worse, ignorance or apathy?
I don&#39;t know and I don&#39;t care.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- same as above, but using &amp;lt;pre&amp;gt; --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;pre&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;What&#39;s worse, ignorance or apathy?
I don&#39;t know and I don&#39;t care.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;pre&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&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;p&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;white-space&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pre&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 selector&quot;&gt;pre&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;/* &amp;lt;pre&amp;gt; sets font-family: monospace, but we can undo that */&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;font-family&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; inherit&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;p class=&quot;codepen&quot; data-height=&quot;570&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;LYQEyOV&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 570px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/LYQEyOV&quot;&gt;Preformatted Text&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;h2 id=&quot;a-break-where-words-cant-break&quot;&gt;&lt;a href=&quot;#a-break-where-words-cant-break&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;A Break, Where Words Can’t Break?&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;For line breaks, you can use &lt;code&gt;&amp;lt;br&amp;gt;&lt;/code&gt; inside of an element with &lt;code&gt;white-space: nowrap&lt;/code&gt; or &lt;code&gt;white-space: pre&lt;/code&gt; just fine. The text will wrap.&lt;/p&gt;&lt;p&gt;But what happens if you use &lt;code&gt;&amp;lt;wbr&amp;gt;&lt;/code&gt; in such an element? Kind of a trick question… because browsers don’t agree. Chrome/Edge will recognize the &lt;code&gt;&amp;lt;wbr&amp;gt;&lt;/code&gt; and potentially wrap, while Firefox/Safari won’t.&lt;/p&gt;&lt;p&gt;When it comes to the zero-width space (&lt;code&gt;&amp;amp;ZeroWidthSpace;&lt;/code&gt;) though, browsers are consistent. None will wrap it with &lt;code&gt;white-space: nowrap&lt;/code&gt; or &lt;code&gt;white-space: pre&lt;/code&gt;.&lt;/p&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Darth Vader: Nooooooooooooo&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;br&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;oooo!&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Darth Vader: Nooooooooooooo&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;wbr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;oooo!&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Darth Vader: Nooooooooooooo&amp;amp;ZeroWidthSpace;oooo!&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;510&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;dydPWZG&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 510px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/dydPWZG&quot;&gt;white-space: nowrap + breaking lines&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;h2 id=&quot;non-breaking-spaces&quot;&gt;&lt;a href=&quot;#non-breaking-spaces&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Non-Breaking Spaces&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Sometimes you may want text to wrap freely, except in very specific places. Good news! There are a few specialized HTML entities that let you do exactly this.&lt;/p&gt;&lt;p&gt;A “non-breaking space” (&lt;code&gt;&amp;amp;nbsp;&lt;/code&gt;) is often used to keep space between words, but disallow a line break between them.&lt;/p&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Something I&#39;ve noticed is designers don&#39;t seem to like orphans.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Something I&#39;ve noticed is designers don&#39;t seem to like&lt;span class=&quot;token entity named-entity&quot; title=&quot;&amp;nbsp;&quot;&gt;&amp;amp;nbsp;&lt;/span&gt;orphans.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;460&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;YzePVEW&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 460px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/YzePVEW&quot;&gt;Non-Breaking Space&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;h2 id=&quot;word-joiners-and-non-breaking-hyphens&quot;&gt;&lt;a href=&quot;#word-joiners-and-non-breaking-hyphens&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Word Joiners and Non-Breaking Hyphens&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;It’s possible for text to naturally wrap even without spaces, such as after a hyphen. To prevent wrapping without adding a space, you can use &lt;code&gt;&amp;amp;NoBreak;&lt;/code&gt; (case-sensitive!) to get a “word joiner”. For hyphens specifically, you can get a “non-breaking hyphen” with &lt;code&gt;&amp;amp;#8209;&lt;/code&gt; (it doesn’t have a nice HTML entity name).&lt;/p&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Turn right here to get on I-85.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Turn right here to get on I-&lt;span class=&quot;token entity named-entity&quot; title=&quot;⁠&quot;&gt;&amp;amp;NoBreak;&lt;/span&gt;85.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Turn right here to get on I&lt;span class=&quot;token entity&quot; title=&quot;‑&quot;&gt;&amp;amp;#8209;&lt;/span&gt;85.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;540&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;vYdEmWX&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 540px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/vYdEmWX&quot;&gt;Word Joiners and Non-Breaking Hyphens&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;h2 id=&quot;cjk-text-and-breaking-words&quot;&gt;&lt;a href=&quot;#cjk-text-and-breaking-words&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;CJK Text and Breaking Words&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;CJK (Chinese/Japanese/Korean) text behaves differently than non-CJK text in some ways. Certain CSS properties and values can be used for additional control over the wrapping of CJK text specifically.&lt;/p&gt;&lt;p&gt;Default browser behavior allows words to be broken in CJK text. This means that &lt;code&gt;word-break: normal&lt;/code&gt; (the default) and &lt;code&gt;word-break: break-all&lt;/code&gt; will give you the same results. However, you can use &lt;code&gt;word-break: keep-all&lt;/code&gt; to prevent CJK text from wrapping within words (non-CJK text will be unaffected).&lt;/p&gt;&lt;p&gt;Here’s an example in Korean. Note how the word “자랑스럽게” does or doesn’t break.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;540&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;MWQYmVZ&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 540px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/MWQYmVZ&quot;&gt;CJK Text + word-break&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;Be careful though, Chinese and Japanese don’t use spaces between words like Korean does, so &lt;code&gt;word-break: keep-all&lt;/code&gt; can easily cause long overflowing text if not otherwise handled.&lt;/p&gt;&lt;h2 id=&quot;cjk-text-and-line-break-rules&quot;&gt;&lt;a href=&quot;#cjk-text-and-line-break-rules&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;CJK Text and Line Break Rules&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We talked about &lt;code&gt;line-break: anywhere&lt;/code&gt; earlier with non-CJK text and how it has no problem breaking at punctuation. The same is true with CJK text.&lt;/p&gt;&lt;p&gt;Here’s an example in Japanese. Note how “。” is or isn’t allowed to start a line.&lt;/p&gt;&lt;p class=&quot;codepen&quot; data-height=&quot;400&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;ZErYKxw&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/ZErYKxw&quot;&gt;CJK Text + line-break&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;There are other values for &lt;code&gt;line-break&lt;/code&gt; that affect how CJK text wraps: &lt;code&gt;loose&lt;/code&gt;, &lt;code&gt;normal&lt;/code&gt;, and &lt;code&gt;strict&lt;/code&gt;. These values instruct the browser on which rules to use when deciding where to insert line breaks. The W3C &lt;a href=&quot;https://drafts.csswg.org/css-text-3/#line-break-property&quot;&gt;describes several rules&lt;/a&gt; and it’s possible for browsers to add their own rules as well.&lt;/p&gt;&lt;h2 id=&quot;worth-mentioning-element-overflow&quot;&gt;&lt;a href=&quot;#worth-mentioning-element-overflow&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Worth Mentioning: Element Overflow&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;overflow&lt;/code&gt; CSS property isn’t specific to text, but is often used to ensure text doesn’t render outside of an element that has its width or height constrained.&lt;/p&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;.top&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;white-space&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; nowrap&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;overflow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; auto&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 selector&quot;&gt;.bottom&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;white-space&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; nowrap&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;overflow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; hidden&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;p class=&quot;codepen&quot; data-height=&quot;350&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;rNJamdb&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 350px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/rNJamdb&quot;&gt;Element Overflow&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;As you can see, a value of &lt;code&gt;auto&lt;/code&gt; allows the content to be scrolled (&lt;code&gt;auto&lt;/code&gt; only shows scrollbars when needed, &lt;code&gt;scroll&lt;/code&gt; shows them always). A value of &lt;code&gt;hidden&lt;/code&gt; simply cuts off the content and leaves it at that.&lt;/p&gt;&lt;p&gt;&lt;code&gt;overflow&lt;/code&gt; is actually shorthand to set both &lt;code&gt;overflow-x&lt;/code&gt; and &lt;code&gt;overflow-y&lt;/code&gt;, for horizontal and vertical overflow respectively. Feel free to use what suits you best.&lt;/p&gt;&lt;p&gt;We can build upon &lt;code&gt;overflow: hidden&lt;/code&gt; by adding &lt;code&gt;text-overflow: ellipsis&lt;/code&gt;. Text will still be cut off, but we’ll get some nice ellipsis as an indication.&lt;/p&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;p&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;white-space&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; nowrap&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;overflow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; hidden&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;text-overflow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ellipsis&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;p class=&quot;codepen&quot; data-height=&quot;220&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;XWZJREw&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 220px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/XWZJREw&quot;&gt;text-overflow: ellipsis&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;h2 id=&quot;bonus-trick-pseudo-element-line-break&quot;&gt;&lt;a href=&quot;#bonus-trick-pseudo-element-line-break&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Bonus Trick: Pseudo-Element Line Break&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;You can force a line break before and/or after an inline element, while keeping it as an inline element, with a little bit of pseudo-element trickery.&lt;/p&gt;&lt;p&gt;First, set the &lt;code&gt;content&lt;/code&gt; of a &lt;code&gt;::before&lt;/code&gt; or &lt;code&gt;::after&lt;/code&gt; pseudo-element to &lt;code&gt;&#39;&#92;A&#39;&lt;/code&gt;, which will give you the new line character. Then set &lt;code&gt;white-space: pre&lt;/code&gt; to ensure the new line character is respected.&lt;/p&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Things that go &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;bump&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; in the night.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&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;span&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; #000&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 selector&quot;&gt;span::before, span::after&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;&#92;A&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;white-space&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pre&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;p class=&quot;codepen&quot; data-height=&quot;290&quot; data-theme-id=&quot;49548&quot; data-default-tab=&quot;result&quot; data-slug-hash=&quot;eYVmWMX&quot; data-user=&quot;lonekorean&quot; style=&quot;height: 290px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/lonekorean/pen/eYVmWMX&quot;&gt;Pseudo-Element Line Breaks&lt;/a&gt; by Will Boyd (&lt;a href=&quot;https://codepen.io/lonekorean&quot;&gt;@lonekorean&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;We could have just put &lt;code&gt;display: block&lt;/code&gt; on the &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; to get the same breaks, but then it would no longer be inline. The &lt;code&gt;background-color&lt;/code&gt; makes it easy to see that with this method, we still have an inline element.&lt;/p&gt;&lt;h2 id=&quot;bonus-notes&quot;&gt;&lt;a href=&quot;#bonus-notes&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Bonus Notes&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;There’s an older CSS property named &lt;code&gt;word-wrap&lt;/code&gt;. It’s non-standard and browsers now treat it as an alias for &lt;code&gt;overflow-wrap&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The &lt;code&gt;white-space&lt;/code&gt; CSS property has some &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/white-space#values&quot;&gt;other values&lt;/a&gt; we didn’t cover: &lt;code&gt;pre-wrap&lt;/code&gt;, &lt;code&gt;pre-line&lt;/code&gt;, and &lt;code&gt;break-spaces&lt;/code&gt;. Unlike the ones we did cover, these don’t prevent text wrapping.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The CSS Text Module Level 4 spec &lt;a href=&quot;https://www.w3.org/TR/css-text-4/#text-wrap&quot;&gt;describes&lt;/a&gt; a &lt;code&gt;text-wrap&lt;/code&gt; CSS property that looks interesting, but at the time of writing, no browser implements it.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Update: Browsers have implemented it! Read more about &lt;a href=&quot;https://codersblock.com/blog/nicer-text-wrapping-with-css-text-wrap/&quot;&gt;how to use it for nicer text wrapping&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;time-to-wrap-things-up&quot;&gt;&lt;a href=&quot;#time-to-wrap-things-up&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Time to “Wrap” Things Up&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;There’s &lt;a href=&quot;https://raphlinus.github.io/text/2020/10/26/text-layout.html#line-breaking&quot;&gt;so much that goes into flowing text&lt;/a&gt; on a web page. Most of the time you don’t really need to think about it, since browsers handle it for you. For the times when you do need more control, it’s nice to know that you have a lot of options.&lt;/p&gt;&lt;p&gt;Writing this was definitely a rabbit hole for me as I kept finding more and more things to talk about. I hope I’ve shown you enough to get your text to break and flow just the way you want it.&lt;/p&gt;&lt;p&gt;Thanks for reading!&lt;/p&gt;</description>
      </item>
      
      <item>
        <guid>https://codersblock.com/blog/making-a-heart-light-with-ifttt-and-netlify-functions/</guid>
        <title>Making a Heart Light with IFTTT and Netlify Functions</title>
        <link>https://codersblock.com/blog/making-a-heart-light-with-ifttt-and-netlify-functions/</link>
        <pubDate>Wed, 01 Dec 2021 00:00:00 GMT</pubDate>
        <description>&lt;p&gt;I had an idea. What if I put a heart icon on my blog, and when people click it, an actual (heart-shaped) light in my room turns on? Just a fun little way for folks reading my blog to send some love.&lt;/p&gt;&lt;p&gt;So I built it. It was fun! Here’s a quick video of the end result.&lt;/p&gt;&lt;div class=&quot;post-iframe-wrapper&quot; style=&quot;padding-bottom: 56.25%;&quot;&gt;&lt;iframe src=&quot;https://www.youtube-nocookie.com/embed/OHfLv27EkSs&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;If you’re interested in how I did it, read on.&lt;/p&gt;&lt;h2 id=&quot;the-main-pieces&quot;&gt;&lt;a href=&quot;#the-main-pieces&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;The Main Pieces&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;There were 3 main pieces I put together to make this work.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;a href=&quot;https://www.belkin.com/us/smart-home/wemo/wemo-wifi-smart-plug/p/p-wsp080/&quot;&gt;Wemo Smart Plug&lt;/a&gt; — The physical device that turns the light on and off.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://ifttt.com/&quot;&gt;IFTTT&lt;/a&gt; — To set up a webhook that sends a signal to the Wemo Smart Plug.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.netlify.com/products/functions/&quot;&gt;Netlify Functions&lt;/a&gt; — To create an intermediary between my blog and the webhook. Not strictly necessary, but a good idea for reasons I’ll get into later.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Let’s talk through each one.&lt;/p&gt;&lt;h2 id=&quot;wemo-smart-plug&quot;&gt;&lt;a href=&quot;#wemo-smart-plug&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Wemo Smart Plug&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;First we need something that can receive signals over the internet to turn the light on and off. I’m not much of a hardware engineer, so I was happy to get a wi-fi enabled smart plug to handle this job. I settled on the &lt;a href=&quot;https://www.belkin.com/us/smart-home/wemo/wemo-wifi-smart-plug/p/p-wsp080/&quot;&gt;Wemo Smart Plug&lt;/a&gt;. I got a 3-pack, but you could just buy a single.&lt;/p&gt;&lt;div class=&quot;post-image-wrapper&quot;&gt;&lt;img src=&quot;https://codersblock.com/assets/images/blog/wemo-smart-plug-3-pack.jpg&quot; alt=&quot;Wemo Smart Plug 3-pack&quot; width=&quot;800&quot; height=&quot;580&quot; loading=&quot;lazy&quot;&gt;&lt;/div&gt;&lt;p&gt;Setup was simple enough. Plug the smart plug into an outlet and the light into the smart plug. Download the app, create a Wemo account, and connect the smart plug to your wi-fi network (it’s easy to do in the app).&lt;/p&gt;&lt;div class=&quot;post-image-wrapper&quot;&gt;&lt;img src=&quot;https://codersblock.com/assets/images/blog/wemo-app-with-heart-light.jpg&quot; alt=&quot;Wemo app with heart light&quot; width=&quot;800&quot; height=&quot;558&quot; loading=&quot;lazy&quot;&gt;&lt;/div&gt;&lt;p&gt;At this point you can use the app to turn the smart plug (and consequently, the light) on and off. That’s cool, but the real fun is getting something else to control the smart plug. That’s where IFTTT comes in.&lt;/p&gt;&lt;h2 id=&quot;ifttt&quot;&gt;&lt;a href=&quot;#ifttt&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;IFTTT&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://ifttt.com/&quot;&gt;IFTTT&lt;/a&gt; (IF This Then That) is a service that lets you connect things by creating cause-and-effect relationships in the form of &lt;strong&gt;applets&lt;/strong&gt;. It’s great because the interface for setting up an applet is very easy to work with, while all the tricky API stuff is handled for you. IFTTT lets you create up to 5 applets for free.&lt;/p&gt;&lt;div class=&quot;post-image-wrapper&quot;&gt;&lt;img src=&quot;https://codersblock.com/assets/images/blog/if-this-then-that.png&quot; alt=&quot;Creating a new applet in IFTTT&quot; width=&quot;800&quot; height=&quot;566&quot; loading=&quot;lazy&quot;&gt;&lt;/div&gt;&lt;p&gt;For this project, we want to create an applet such that &lt;strong&gt;if&lt;/strong&gt; a webhook receives a request, &lt;strong&gt;then&lt;/strong&gt; turn the smart plug on and off. The webhook will live at a specially crafted URL that IFTTT will host for us. Pinging the URL triggers the webhook (which triggers the smart plug).&lt;/p&gt;&lt;p&gt;Here are the steps to set this up.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Head over to IFTTT and &lt;a href=&quot;https://ifttt.com/join&quot;&gt;create your account&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Once you’ve logged in, &lt;a href=&quot;https://ifttt.com/create&quot;&gt;create an applet&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Click &lt;strong&gt;If This&lt;/strong&gt;, search for “webhooks”, click on it.&lt;/li&gt;&lt;li&gt;Click &lt;strong&gt;Receive a web request&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;Name the event (“heart_light” is what I used) and click &lt;strong&gt;Create trigger&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;Now click &lt;strong&gt;Then That&lt;/strong&gt;, search for “wemo smart plug”, click on it.&lt;/li&gt;&lt;li&gt;Click &lt;strong&gt;Turn on then off&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;Click &lt;strong&gt;Connect&lt;/strong&gt; and sign into your Wemo account.&lt;/li&gt;&lt;li&gt;Select your smart plug from the dropdown and click &lt;strong&gt;Create action&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;Click &lt;strong&gt;Continue&lt;/strong&gt;, then click &lt;strong&gt;Finish&lt;/strong&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;To find your webhook URL, go to &lt;a href=&quot;https://ifttt.com/maker_webhooks&quot;&gt;this webhooks page&lt;/a&gt; and click the &lt;strong&gt;Documentation&lt;/strong&gt; button. The URL will look something like this.&lt;/p&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;https://maker.ifttt.com/trigger/heart_light/with/key/YOUR_KEY&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can test that URL from that same page, or you can go to it directly from your browser. When you do, you should see your light turn on and off.&lt;/p&gt;&lt;p&gt;Now we have everything we need to add a clickable &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; to a web page that pings the webhook and triggers the light.&lt;/p&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;❤️ click me!&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;button&#39;&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;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;click&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ping&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 keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ping&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 punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;https://maker.ifttt.com/trigger/heart_light/with/key/YOUR_KEY&#39;&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 punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It’s happening!&lt;/p&gt;&lt;h2 id=&quot;netlify-functions&quot;&gt;&lt;a href=&quot;#netlify-functions&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Netlify Functions&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We have a working project at this point, but there’s one thing I’m not thrilled about. The client-side JavaScript shown above pings the webhook URL directly, which means &lt;strong&gt;the URL and our key are exposed publicly&lt;/strong&gt;. Sometimes this is totally fine, but personally I’d prefer to keep them secret.&lt;/p&gt;&lt;p&gt;My solution is to use &lt;a href=&quot;https://www.netlify.com/products/functions/&quot;&gt;Netlify Functions&lt;/a&gt; to create an API endpoint — basically just a different URL to ping. When pinged, it’ll run server-side JavaScript that turns around and pings the IFTTT webhook URL. Since it’s server-side, the webhook URL and key are not exposed. As a bonus, this also gives us an opportunity to &lt;strong&gt;do other things server-side&lt;/strong&gt;, like logging.&lt;/p&gt;&lt;p&gt;I put together an &lt;a href=&quot;https://github.com/lonekorean/heart-light&quot;&gt;example repo&lt;/a&gt; to show exactly how to do this. Let’s cover the highlights.&lt;/p&gt;&lt;p&gt;The code for the server-side function is in &lt;code&gt;/netlify/functions/heart-light.js&lt;/code&gt;. It pings the IFTTT webhook URL, logs the response, and then returns its own response depending on if the ping went OK or not.&lt;/p&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fetch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;node-fetch&#39;&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;

exports&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&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 operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; url &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;https://maker.ifttt.com/trigger/heart_light/with/key/YOUR_KEY&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// change this!&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&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 keyword&quot;&gt;const&lt;/span&gt; text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;text&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 punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&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 keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ok&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 keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;statusCode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Success!&#39;&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 punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;statusCode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Error.&#39;&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 punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The code has a single dependency on &lt;code&gt;node-fetch&lt;/code&gt;, so we need to declare that in &lt;code&gt;/package.json&lt;/code&gt;.&lt;/p&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token property&quot;&gt;&quot;devDependencies&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;node-fetch&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;^2.6.6&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that we’re using &lt;code&gt;node-fetch&lt;/code&gt; v2. That’s because &lt;code&gt;node-fetch&lt;/code&gt; was &lt;a href=&quot;https://github.com/node-fetch/node-fetch/blob/main/docs/v3-UPGRADE-GUIDE.md#converted-to-es-module&quot;&gt;converted to an ES module&lt;/a&gt; as of v3, which doesn’t work with Netlify functions out of the box. You can make it happen with &lt;a href=&quot;https://www.netlify.com/blog/2021/04/02/modern-faster-netlify-functions/#how-to-enable-the-new-bundler&quot;&gt;some extra steps&lt;/a&gt; or just install v2 explicitly.&lt;/p&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; node-fetch@^2 --save-dev&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now the client-side JavaScript can call the function instead of calling the IFTTT webhook directly. You can see this in &lt;code&gt;/page.js&lt;/code&gt;. Note that the function file lives at &lt;code&gt;/netlify/functions/heart-light.js&lt;/code&gt; but we call the function at &lt;code&gt;/.netlify/functions/heart-light&lt;/code&gt;!&lt;/p&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;button&#39;&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;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;click&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ping&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 keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ping&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 punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/.netlify/functions/heart-light&#39;&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 punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;a href=&quot;https://github.com/lonekorean/heart-light&quot;&gt;example repo&lt;/a&gt; we’ve been looking at is a (small) fully functional Netlify site. You can get it up and running locally via the command line.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;a href=&quot;https://docs.netlify.com/cli/get-started/#installation&quot;&gt;Install the Netlify CLI&lt;/a&gt; with &lt;code&gt;npm install netlify-cli -g&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Install the example repo’s dependencies with &lt;code&gt;npm install&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://docs.netlify.com/cli/get-started/#run-a-local-development-environment&quot;&gt;Start a local dev server&lt;/a&gt; with &lt;code&gt;netlify dev&lt;/code&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Here’s what you’ll see when you run &lt;code&gt;netlify dev&lt;/code&gt; and then click the button on the page. Success!&lt;/p&gt;&lt;div class=&quot;post-image-wrapper&quot;&gt;&lt;img src=&quot;https://codersblock.com/assets/images/blog/netlify-dev-command-line.png&quot; alt=&quot;Netlify dev command line with logging&quot; width=&quot;800&quot; height=&quot;448&quot; loading=&quot;lazy&quot;&gt;&lt;/div&gt;&lt;p&gt;My site is already hosted on Netlify, so I incorporated the Netlify function into my existing codebase. If that’s not the case for you, then you can still &lt;a href=&quot;https://docs.netlify.com/site-deploys/create-deploys/&quot;&gt;deploy&lt;/a&gt; a standalone Netlify site with just the function and have your existing site ping it with an absolute URL.&lt;/p&gt;&lt;h2 id=&quot;wrapping-up&quot;&gt;&lt;a href=&quot;#wrapping-up&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use xlink:href=&quot;#link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;span&gt;Wrapping Up&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;That’s about it. You’ve probably already noticed the heart icon on this page. Now you know what it does and how it works. Thanks for reading!&lt;/p&gt;</description>
      </item>
  </channel>
</rss>
