<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Riley McMaster</title>
    <description>The latest articles on Forem by Riley McMaster (@rileymcmaster).</description>
    <link>https://forem.com/rileymcmaster</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1083838%2Fec840e50-235a-4589-817d-11d2b0aaa9df.jpeg</url>
      <title>Forem: Riley McMaster</title>
      <link>https://forem.com/rileymcmaster</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rileymcmaster"/>
    <language>en</language>
    <item>
      <title>The REM to PX relation: how to write more accessible media queries</title>
      <dc:creator>Riley McMaster</dc:creator>
      <pubDate>Mon, 26 Aug 2024 15:45:29 +0000</pubDate>
      <link>https://forem.com/plank/the-rem-to-px-relation-how-to-write-more-accessible-media-queries-5f95</link>
      <guid>https://forem.com/plank/the-rem-to-px-relation-how-to-write-more-accessible-media-queries-5f95</guid>
      <description>&lt;p&gt;We are developers. We want to develop the most responsive layouts. We want to accommodate different devices, resolutions and user settings. We want to use consistent units across all stylesheets. We want to do as little math as possible. &lt;/p&gt;

&lt;p&gt;When do we want this? NOW!&lt;br&gt;
What do we need to know? Lots of stuff!&lt;br&gt;
How do we do this? With a custom SASS function!&lt;/p&gt;

&lt;p&gt;By using a SASS function, we can accommodate more users by understanding and accounting for their system and browser-level settings. I will go over how rem values relate to pixel values and what might affect the relation between them. 1rem almost always starts off as 16px but there are ways a user can change that. This SASS function we’ll write later is very helpful because it can apply to a larger project and it can be introduced incrementally into your existing projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;What got me looking into this topic was the article &lt;a href="https://bootcamp.uxdesign.cc/theres-no-such-thing-as-a-desktop-screen-b9e300c0b128" rel="noopener noreferrer"&gt;There’s No Such Thing as a Desktop Screen&lt;/a&gt;, Hajime Yamasaki Vukelic,  where his take on responsive design is that “responsiveness is not about a simple set of arbitrary screen widths.... responsiveness is about robustness: how much can you stretch or squeeze the page before it starts falling apart”. Hajime talks about how his father is browsing the web at essentially 400% regular scale. While this may seem like an edge case, it’s important to know the different ways a user may scale their display and how the styles we’re writing are affected by these changes in settings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaled display
&lt;/h2&gt;

&lt;p&gt;Let’s start as small as possible with understanding exactly what a pixel is. As far as a developer is concerned, there are two types of pixels: there are device pixels which are the amount of dots of light on a given screen and there are CSS pixels which are a unit of measurement. Device pixels usually do not equal CSS pixels. It’s important to understand the difference between the two so we can figure which settings affect each value.&lt;/p&gt;

&lt;p&gt;There are several ways that a user can change the size of the content on their screen like Hajime’s father. The most common ways that a user could scale their display: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;changing the display resolution (system setting)&lt;/li&gt;
&lt;li&gt;zooming in on the browser tab (on Mac pressing &lt;code&gt;⌘ and +&lt;/code&gt;, windows &lt;code&gt;Ctrl and +&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;increasing the font size in the browser’s settings. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first and second options, changing the display resolution and zooming in the browser, essentially do the same thing. Both methods will scale the CSS pixels so that each CSS pixel takes up more device pixels. In this case, our layout all scales proportionally. 1rem will still equal 16px but each CSS pixel takes up more device pixels. To test this, you can zoom in on the browser tab until you trigger the “mobile” layout. This setting is quick to test and generally shouldn’t cause much issue. &lt;/p&gt;

&lt;p&gt;Changing the browser font size will cause the most change. By default, the browser’s setting is “medium” which in Chrome means 1rem is 16px. When the user increases the font size, the value of 1rem will increase but no other values will scale. 1rem will equal more CSS pixels and therefore take up more device pixels. On Chrome, with the font size set to “very large”, 1rem will equal 24px. The size of the CSS pixels remain the same, it is the root font size that has changed. Any value that references the root font size will be affected.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsh96gdbv5gw2q4efzbp2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsh96gdbv5gw2q4efzbp2.jpg" alt="two variations of the same layout that consists of an image on the left and on the right a heading and text all bordered in a smooth drop shadow. The first variation is properly proportioned. The second example with the browser's font size set to "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In your code, If you have a mix of pixel and rem values then you might start to have layout issues since the rem values will scale but the pixel values will stay the same. The image above shows how a simple example of how drastically the layout can change when the text is set in rem values while the max-width, column width and paddings are set with pixel values. A responsive layout should scale accordingly with the root font size.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with media queries
&lt;/h2&gt;

&lt;p&gt;This is generally how we write a media query:&lt;/p&gt;

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

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1000px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="nc"&gt;.declarations&lt;/span&gt; &lt;span class="nt"&gt;here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Since we’re trying to be responsive and adaptable to all of the users’ settings, we want to use relative units all everywhere that we can. Let’s use a rem value instead of pixels in the media query:&lt;/p&gt;

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

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;62.5rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="nc"&gt;.declarations&lt;/span&gt; &lt;span class="nt"&gt;here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;With the default browser settings, 1000px will equal 62.5rem&lt;br&gt;
1rem = 16px&lt;br&gt;
1000px / 16px/rem = 62.5rem&lt;br&gt;
That looks like math I have to do every time I want to write a relative unit. We said right at the start that we don’t want to have to do math. &lt;/p&gt;

&lt;p&gt;There is a common fix that we’ve all seen where we make 1rem = 10px. This is generally done while setting up the boilerplate of a project. You overwrite the root font size on the root element by targeting the &lt;code&gt;html&lt;/code&gt; selector:&lt;/p&gt;

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

&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;62.5%&lt;/span&gt; 
    &lt;span class="p"&gt;//&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt; 
    &lt;span class="p"&gt;//&lt;/span&gt; &lt;span class="n"&gt;but&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;needs&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;done&lt;/span&gt; &lt;span class="nb"&gt;once&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;whole&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt; 
    &lt;span class="p"&gt;//&lt;/span&gt; &lt;span class="n"&gt;so&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;ll&lt;/span&gt; &lt;span class="n"&gt;let&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;slide&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now any time we want to convert a pixel value from the design to a rem value in our code we just have to carry the decimal one place.&lt;br&gt;
1rem = 10px&lt;br&gt;
To get a value of 1000px, we use 100rem. This still involves math but is fairly minor. &lt;/p&gt;

&lt;p&gt;Now, when using a rem value, we can safely assume that 1rem will be 10px. &lt;br&gt;
Right? &lt;br&gt;
Yes? &lt;br&gt;
Example? &lt;br&gt;
No need. We know it is true. We have used rem for widths, heights, paddings, margins, translates or any other declaration without any issue. But…will there be any issue using it in the condition for a media query?&lt;/p&gt;

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

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nt"&gt;does&lt;/span&gt; &lt;span class="nt"&gt;is&lt;/span&gt; &lt;span class="nt"&gt;trigger&lt;/span&gt; &lt;span class="nt"&gt;at&lt;/span&gt; &lt;span class="err"&gt;1000&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;as&lt;/span&gt; &lt;span class="nt"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;
    &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="nc"&gt;.declarations&lt;/span&gt; &lt;span class="nt"&gt;here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/plankdesign/embed/YzbEojr?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;br&gt;
Open the example in a new window and play with the width of the viewport. When the “desktop” media query triggers then the background will turn blue.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is happening?
&lt;/h2&gt;

&lt;p&gt;The values for a media query are calculated before any other rules are set, so the ruleset we applied to the &lt;code&gt;html&lt;/code&gt; element in the start of our project will not be applied in the condition of the media query. According to this media query, 1rem is still equal to 16px. We expected 100rem to be 1000px but it ended up being 1600px.&lt;/p&gt;

&lt;p&gt;If you change the browser font size to “very large” and refresh the example, you will notice that 1rem = 15px and the 100rem media query won’t trigger until 2400px. If your monitor isn’t wide enough to see that change happen, zoom out on the browser with ⌘/Ctrl and + .&lt;/p&gt;

&lt;p&gt;The condition for the media query is not scaling consistently with the browser’s desired font size. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Font size “Medium”: 

&lt;ul&gt;
&lt;li&gt;1rem = 10px&lt;/li&gt;
&lt;li&gt;Media query: 100rem = 1600px&lt;/li&gt;
&lt;li&gt;rem to px ratio: 0.0625&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Font size “Very Large”:

&lt;ul&gt;
&lt;li&gt;1rem = 15px&lt;/li&gt;
&lt;li&gt;Media query: 100rem = 2400px&lt;/li&gt;
&lt;li&gt;rem to px ratio: 0.0416666667&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;For content and layouts to scale consistently, we need the rem to px ratio to always remain the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  REMPX()
&lt;/h2&gt;

&lt;p&gt;This has taken a long time to get to even suggesting a solution to a problem that we maybe didn’t know we had. &lt;/p&gt;

&lt;p&gt;Let’s create a custom SASS function that will allow us to write our code in pixel values and be rendered as rem values. I came across this function on a legacy project at work but I believe it was heavily inspired by this quick article: &lt;a href="https://medium.com/@bhargav3shah/scss-convert-pixel-values-to-rem-using-functions-f1cef575edfd" rel="noopener noreferrer"&gt;Convert pixel values to rem, Sass style&lt;/a&gt;, by Bhargav Shah. Since this article was written, CSS introduced its own &lt;code&gt;rem()&lt;/code&gt; function which calculates the remainder of a fraction so instead we’ll name our function &lt;code&gt;rempx()&lt;/code&gt;.&lt;/p&gt;

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

&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;html-font-size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;16&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@function&lt;/span&gt; &lt;span class="n"&gt;stripUnit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;@return&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@function&lt;/span&gt; &lt;span class="n"&gt;rempx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;pxValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;@return&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;stripUnit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;pxValue&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nt"&gt;stripUnit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;html-font-size&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nt"&gt;implementation&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="nc"&gt;.image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rempx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;300px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/plankdesign/embed/zYQPVLr?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;br&gt;
Open the example in a new window and play with the width of the viewport and change the browser font size (refresh the page after you update the font size).&lt;/p&gt;

&lt;p&gt;Notice how after we change the browser font size to “very large” (after a page a refresh), the 1rem square becomes larger and you can see that 1rem is equal to 24px.&lt;/p&gt;

&lt;p&gt;When used in the condition of a media query, a &lt;code&gt;rempx&lt;/code&gt; value will scale accordingly with the browsers font size. With the font size set to “very large”, the desktop layout &lt;code&gt;rempx(1000px)&lt;/code&gt; will trigger at the viewport width of 1500px. The scaling of the content and layout behave the same way as when we zoom in on the browser. &lt;/p&gt;

&lt;p&gt;A huge benefit of writing all your units with the &lt;code&gt;rempx()&lt;/code&gt; function is you can write pixel values from the designs and then it renders it as a rem value in the browser. This function is very easy to introduce to a project or include in the boilerplate of your future projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;This function can be written once and used everywhere. &lt;br&gt;
We can take the pixel values from the design and generate a scalable rem value. &lt;br&gt;
Our media query triggers relative to the root font size.&lt;br&gt;
All our layout and content scales consistently.&lt;br&gt;
No math necessary.&lt;br&gt;
Better user experience across a wider range of user settings. &lt;br&gt;
Better user existence overall.&lt;br&gt;
Better developer existence overall.&lt;br&gt;
This function improves our existence. &lt;/p&gt;

&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://bootcamp.uxdesign.cc/theres-no-such-thing-as-a-desktop-screen-b9e300c0b128" rel="noopener noreferrer"&gt;There’s No Such Thing as a Desktop Screen&lt;/a&gt; Hajime Yamasaki Vukelic&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.oddbird.net/2024/07/09/zoomies/" rel="noopener noreferrer"&gt;Zoom, zoom, and zoom: the three types of browser (and CSS!) magnification&lt;/a&gt;, Miriam Suzanne&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@bhargav3shah/scss-convert-pixel-values-to-rem-using-functions-f1cef575edfd" rel="noopener noreferrer"&gt;Convert pixel values to rem, Sass style&lt;/a&gt;, Bhargav Shah&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>sass</category>
      <category>a11y</category>
    </item>
    <item>
      <title>Why Did You Render - React &amp; WordPress</title>
      <dc:creator>Riley McMaster</dc:creator>
      <pubDate>Thu, 01 Feb 2024 19:46:30 +0000</pubDate>
      <link>https://forem.com/plank/why-did-you-render-react-wordpress-1flg</link>
      <guid>https://forem.com/plank/why-did-you-render-react-wordpress-1flg</guid>
      <description>&lt;p&gt;When using React components in a WordPress project, I want to be able to diagnose what is causing components to re-render unnecessarily. &lt;/p&gt;

&lt;p&gt;On a project recently, I ran into a problem where a React component was re-rendering unexpectedly. It was causing a quick layout shift and I was finding it really difficult to troubleshoot what was the cause. I came across the package &lt;code&gt;why-did-you-render&lt;/code&gt; and the docs didn't have any tips on how to get it set up on a WordPress project. Below are the steps that my backend dev &lt;a class="mentioned-user" href="https://dev.to/davekellam"&gt;@davekellam&lt;/a&gt; and I took to get the package working with WordPress. We compile assets in our WordPress projects with Webpack and Babel. &lt;/p&gt;

&lt;p&gt;We had to add a couple of dependencies and update the &lt;code&gt;.babelrc&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Dev dependencies to add to project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;babel&lt;/span&gt;&lt;span class="sr"&gt;/preset-reac&lt;/span&gt;&lt;span class="err"&gt;t
&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;welldone&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;software&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;why&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;did&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;you&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;.babelrc&lt;/code&gt; (add this line underneath &lt;code&gt;@babel/preset-env&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;presets&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@babel/preset-env&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@babel/preset-react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// added this line&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@wordpress/default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we don't have access to an &lt;code&gt;.env&lt;/code&gt; file, we had to add this next line in order to access the environment via the &lt;code&gt;global mainScript&lt;/code&gt;. This will prevent the script from loading in production if we have forgotten to remove the dependency. &lt;br&gt;
&lt;code&gt;scripts.php&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;environment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;esc_attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;wp_get_environment_type&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuwihqbpf14cxj2fyib6r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuwihqbpf14cxj2fyib6r.png" alt="Snippet of code used to access env variable" width="800" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the top level .js file, in this case mine is called &lt;code&gt;frontend.js&lt;/code&gt;, (need &lt;code&gt;global mainscript&lt;/code&gt;, the code below will be placed above the individual component imports):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* global mainScript */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;whyDidYouRender&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@welldone-software/why-did-you-render&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainScript&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;local&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;whyDidYouRender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;trackAllPureComponents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in a component file, with &lt;code&gt;ComponentName&lt;/code&gt; replaced with the actual name of the component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ComponentName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;whyDidYouRender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WDYR wants to only display a message if a component re-renders with the same props. If your component isn't getting re-rendered unnecessarily then you might not get an error message and it might seem like the package is not doing anything. Using this next code snippet instead will display any prop changes that happen. The result is a bit verbose but a simple test to make sure that the package is working.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ComponentName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;whyDidYouRender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;logOnDifferentValues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am still encountering an issue of loading the package in the production environment. The package's docs have an example for how to conditionally import the package but I was unable to find a workaround in WordPress. The best course of action I can find is to either remove the dependency before the site is deployed or install the package when debugging and remove it before merging your branch. &lt;/p&gt;

&lt;p&gt;More information about the use-cases for WDYR and an example on how to use it: &lt;br&gt;
&lt;a href="https://blog.logrocket.com/debugging-react-performance-issues-with-why-did-you-render/"&gt;https://blog.logrocket.com/debugging-react-performance-issues-with-why-did-you-render/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>wordpress</category>
      <category>tutorial</category>
      <category>frontend</category>
    </item>
    <item>
      <title>VoiceOver quick start</title>
      <dc:creator>Riley McMaster</dc:creator>
      <pubDate>Fri, 03 Nov 2023 14:04:40 +0000</pubDate>
      <link>https://forem.com/plank/voiceover-quick-start-2ki2</link>
      <guid>https://forem.com/plank/voiceover-quick-start-2ki2</guid>
      <description>&lt;p&gt;VoiceOver is a screen reader that comes installed on all Apple computers. This article will serve as a quick introduction to some of the basic commands to help you get started using a screen reader on any website. VoiceOver will work in any browser but does work best in Safari. &lt;/p&gt;

&lt;p&gt;The VoiceOver command keys will be used for almost every command going forward. I will refer to the command as &lt;code&gt;VO&lt;/code&gt; which can be either of these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;caps lock&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;option + command&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start VoiceOver - &lt;code&gt;command + F5&lt;/code&gt;&lt;br&gt;
Select &lt;code&gt;use VoiceOver&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It might start reading off all the elements on a webpage without taking a break and this can be a little overwhelming. &lt;/p&gt;

&lt;p&gt;Stop VoiceOver from auto reading - press the &lt;code&gt;control&lt;/code&gt; key.&lt;br&gt;
Start reading again - &lt;code&gt;VO + a&lt;/code&gt; &lt;br&gt;
I wouldn't suggest auto reading for a first-time screen reader user. For now, let's take it one element at a time. &lt;/p&gt;

&lt;p&gt;In the case that the whole browser is selected (you will see an outline around the whole app):&lt;br&gt;
Interact with the item (the browser in this instance) - &lt;code&gt;VO + shift + down&lt;/code&gt;&lt;br&gt;
Stop interacting with an item - &lt;code&gt;VO + shift + up&lt;/code&gt;&lt;br&gt;
This can also be thought of like navigating levels of a directory.&lt;/p&gt;

&lt;p&gt;If the tabs or address bar are selected, you will use &lt;br&gt;
&lt;code&gt;VO + up&lt;/code&gt; or &lt;code&gt;VO + down&lt;/code&gt; until the content of the webpage is selected.&lt;/p&gt;

&lt;p&gt;Once the web content is selected,&lt;br&gt;
navigate between elements on the page:&lt;br&gt;
&lt;code&gt;VO + left arrow&lt;/code&gt; &lt;br&gt;
&lt;code&gt;VO + right arrow&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Open Rotor: &lt;code&gt;VO + u&lt;/code&gt;&lt;br&gt;
This tool is really interesting because it organizes the content of the website in a completely different way than what sighted users are used to seeing. Rotor breaks down the content into several different categories: links, headings, form controls and landmarks.  &lt;/p&gt;

&lt;p&gt;You can navigate between the Rotor sections with the arrow keys.&lt;/p&gt;

&lt;p&gt;Since starting to test the sites that I'm developing with a screen reader, I've found:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"read more" or other vague text in buttons are not helpful. Give buttons like this descriptive aria-labels&lt;/li&gt;
&lt;li&gt;images declared in the content property of pseudo-elements will be read, even though there's no alt or title. &lt;/li&gt;
&lt;li&gt;it's important to connect your labels to your inputs using &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;for&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;use html table elements instead of creating a table visually with divs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is worth exploring how to use screen readers and other assistive technologies in order to become a more empathetic developer. VoiceOver is a great tool that is readily available to all Mac users. While VoiceOver comes with its own tutorial, I found it a bit long and slow but it is definitely worth doing when you have the time. &lt;/p&gt;

&lt;p&gt;To see the whole list of commands:&lt;br&gt;
&lt;a href="https://www.apple.com/voiceover/info/guide/_1131.html"&gt;Apple - VoiceOver commands&lt;/a&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>webdev</category>
      <category>development</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>CSS: complex grid layout</title>
      <dc:creator>Riley McMaster</dc:creator>
      <pubDate>Tue, 12 Sep 2023 13:23:41 +0000</pubDate>
      <link>https://forem.com/plank/css-complex-grid-layout-2jk9</link>
      <guid>https://forem.com/plank/css-complex-grid-layout-2jk9</guid>
      <description>&lt;p&gt;At Plank, we build many of our projects with Wordpress. Making menus in the CMS is pretty user friendly but when it comes to more complex menu structures, it can be difficult for us as the frontend developer to style when all we are given is nested lists upon nested lists. &lt;/p&gt;

&lt;p&gt;To solve this problem, I came up with this grid layout recently and wanted to share how it is done. I’ll also discuss a big struggle I had to overcome for this to work properly, be flexible and easy to tweak. &lt;/p&gt;

&lt;h2&gt;
  
  
  The markup:
&lt;/h2&gt;

&lt;p&gt;In this example, we are working with one unordered list with several children. The first child is a call to action and the rest are links. Wordpress allows us to add classes to the individual links (as well as a description to support the call to action), so I added a class and a description to the call to action &lt;code&gt;list__item--cta&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;I decided to go with grid over flex in this case because the call to action will take the whole vertical height of the menu while the rest of the links were tiled towards the right side of the screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.list&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;need&lt;/span&gt; &lt;span class="err"&gt;to&lt;/span&gt; &lt;span class="err"&gt;name&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;start&lt;/span&gt; &lt;span class="err"&gt;and&lt;/span&gt; &lt;span class="err"&gt;end&lt;/span&gt; &lt;span class="err"&gt;of&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; 
   &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;first&lt;/span&gt; &lt;span class="err"&gt;column&lt;/span&gt; &lt;span class="err"&gt;so&lt;/span&gt; &lt;span class="err"&gt;it&lt;/span&gt; &lt;span class="err"&gt;can&lt;/span&gt; &lt;span class="err"&gt;be&lt;/span&gt; &lt;span class="err"&gt;referenced&lt;/span&gt; &lt;span class="err"&gt;by&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;CTA&lt;/span&gt;
   &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;declare&lt;/span&gt; &lt;span class="err"&gt;4&lt;/span&gt; &lt;span class="err"&gt;columns,&lt;/span&gt; 
   &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;first&lt;/span&gt; &lt;span class="err"&gt;spot&lt;/span&gt; &lt;span class="err"&gt;for&lt;/span&gt; &lt;span class="err"&gt;CTA&lt;/span&gt; &lt;span class="err"&gt;then&lt;/span&gt; &lt;span class="err"&gt;repeat&lt;/span&gt; &lt;span class="err"&gt;3&lt;/span&gt; &lt;span class="err"&gt;for&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;links&lt;/span&gt;
   &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cta-start&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cta-end&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
   &lt;span class="py"&gt;grid-auto-rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;min-content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.list__item--cta&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;grid-row&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;grid-column&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cta-start&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;cta-end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we did not define the amount of rows on the parent, the &lt;code&gt;--cta&lt;/code&gt; child is telling the parent grid how many rows there will be with the property &lt;code&gt;grid-row: 1 / 4;&lt;/code&gt;. The value is spanning from the first line (start of the first row) to the fourth line (end of the third row). In this example we have 7 links, so we need 3 rows and 3 columns (in practice I used a bit of JavaScript to adjust the number of rows and columns based on the number of links). &lt;/p&gt;

&lt;p&gt;I made the description of the call to action &lt;code&gt;contenteditable&lt;/code&gt; to show where I went wrong. Edit the text and see how the grid falls apart&lt;/p&gt;

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

&lt;p&gt;The gap between the rows shouldn't start stretching out like that. So what is there to do?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;Grid will fill its rows before columns by default. We need three rows for the amount of links we have. But what if we create one extra row that starts at a height of 0 and its only job is to expand to take the extra height of the CTA description? In this case, we update the grid-row property on &lt;code&gt;--cta&lt;/code&gt; to create an extra row:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.list__item--cta&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;grid-row&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember that when setting the &lt;code&gt;grid-row&lt;/code&gt; property, the last line in the grid will always be one more than the number of rows.&lt;/p&gt;

&lt;p&gt;The cta is now adding a fourth row that won't be filled up by the other links, the last row only exists as a buffer. If the CTA doesn't need that space, the row will have a height of zero.&lt;/p&gt;

&lt;p&gt;Now we can add as much text as we want to the cta description and the other links will be completely unaffected!&lt;/p&gt;

&lt;h2&gt;
  
  
  The final result:
&lt;/h2&gt;

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

&lt;p&gt;Done!&lt;/p&gt;

</description>
      <category>css</category>
      <category>grid</category>
      <category>tutorial</category>
      <category>wordpress</category>
    </item>
    <item>
      <title>Using the reduced motion media query in a project</title>
      <dc:creator>Riley McMaster</dc:creator>
      <pubDate>Mon, 24 Jul 2023 13:14:31 +0000</pubDate>
      <link>https://forem.com/plank/using-the-reduced-motion-media-query-in-a-project-34gb</link>
      <guid>https://forem.com/plank/using-the-reduced-motion-media-query-in-a-project-34gb</guid>
      <description>&lt;p&gt;The CSS media query &lt;code&gt;prefers-reduced-motion&lt;/code&gt; is a rule that checks the user's accessibility setting for "reduced motion" in their system preferences. It is not browser, website or session dependent but a setting on the user's computer itself. This media query allows us as developers to update any styles based on the user's preference for animation. &lt;/p&gt;

&lt;p&gt;The intent of this media query is to create a comfortable experience for all users. Animations can cause discomfort and even pain for neurodivergent users which can include people with vestibular disorders and users who are prone to inattention due to ADHD, bipolar disorder, depression or anxiety disorders. Other users may wish to turn on "reduced motion" to minimize distractions or reduce cognitive load. &lt;/p&gt;

&lt;p&gt;The problem is that not all sites accommodate the user's wishes and stop animations if they have selected "reduced motion".&lt;/p&gt;

&lt;p&gt;When a user chooses "reduced motion" it does not necessarily mean that they wish to have no motion at all. Some animations are extremely helpful for the user experience in providing visual feedback: a loading spinner that doesn't spin can make the user think the site is frozen, a button changing scale as you click it can emphasize that it has been clicked. Reducing motion is most beneficial when dealing with big parallax effects, scroll hijacking and animations that cover lots of screen space as these are most likely to cause issues for motion-sensitive users. &lt;/p&gt;

&lt;p&gt;A developer's initial instinct to using the &lt;code&gt;prefers-reduced-motion&lt;/code&gt; media query might be to stop animations on an individual selector basis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-reduced-motion&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will likely cause issues because the animations can get stuck at their initial value (ie. opacity: 0 and the position is off screen).&lt;/p&gt;

&lt;p&gt;We want a more global solution that will make it easier to develop for users who want less motion. We also need for the animations to play so that the elements end up at their desired end point, while not noticing the in-between states of the animation. We can use the animation and transition &lt;code&gt;duration&lt;/code&gt; property to force the animations to run at a speed so fast that it is imperceivable. &lt;/p&gt;

&lt;p&gt;In the root level of our CSS, we call the reduced-motion media query and target a specific class that will 'turn off' the animations for those elements.&lt;/p&gt;

&lt;p&gt;A more global and adaptable solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-reduced-motion&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.reduce-motion&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nc"&gt;.reduce-motion&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nc"&gt;.reduce-motion&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0s&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;animation-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.001ms&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;animation-iteration-count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="nl"&gt;transition-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;.0001ms&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transition-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0s&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we are developing, we can add the class &lt;code&gt;reduce-motion&lt;/code&gt; to any elements that we think are not necessary to the user experience or could cause discomfort to the motion-sensitive users. &lt;/p&gt;

&lt;p&gt;While we try to use the &lt;code&gt;!important&lt;/code&gt; property as little as possible, it is a valuable use of it here since the point is to be a global override of any animation and transition properties further down the style-sheet. &lt;/p&gt;

&lt;p&gt;This isn't necessarily a perfect solution but it is important to have these conversations about how different people experience the web. In order to build more inclusive sites, we need to listen to issues people have and address them with any tools that we have available to us. &lt;/p&gt;

&lt;p&gt;Sources that helped inform this article:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://css-tricks.com/revisiting-prefers-reduced-motion/"&gt;https://css-tricks.com/revisiting-prefers-reduced-motion/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://alistapart.com/article/designing-safer-web-animation-for-motion-sensitivity/"&gt;https://alistapart.com/article/designing-safer-web-animation-for-motion-sensitivity/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://alistapart.com/article/designing-for-cognitive-differences/"&gt;https://alistapart.com/article/designing-for-cognitive-differences/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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