<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Stacey</title>
    <description>The latest articles on DEV Community by Stacey (@heyitsstacey).</description>
    <link>https://dev.to/heyitsstacey</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%2F121348%2F77208c81-286f-4438-a73e-031abfd5e23c.png</url>
      <title>DEV Community: Stacey</title>
      <link>https://dev.to/heyitsstacey</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/heyitsstacey"/>
    <language>en</language>
    <item>
      <title>Container queries are live (in Chrome)!</title>
      <dc:creator>Stacey</dc:creator>
      <pubDate>Thu, 08 Sep 2022 02:34:00 +0000</pubDate>
      <link>https://dev.to/heyitsstacey/container-queries-are-live-in-chrome-39ae</link>
      <guid>https://dev.to/heyitsstacey/container-queries-are-live-in-chrome-39ae</guid>
      <description>&lt;p&gt;Update September 14, 2022: Safari 16 now also supports container queries! &lt;/p&gt;




&lt;p&gt;Chrome 105 rolled out some pretty exciting CSS support updates including long-awaited container queries!&lt;/p&gt;

&lt;h2&gt;
  
  
  What are container queries?
&lt;/h2&gt;

&lt;p&gt;Container queries are a new type of CSS query that, like many use cases for media queries, allows us to define styles based on a defined size. However, where &lt;code&gt;@media&lt;/code&gt; encompasses the width of the environment—viewport or user settings like zoom—the new &lt;code&gt;@container&lt;/code&gt; allows us to target specific elements on the page.&lt;/p&gt;

&lt;p&gt;For a potential use case, let’s look at the related news stories section of &lt;a href="https://www.nytimes.com/2022/09/07/technology/apple-new-iphone-watch.html" rel="noopener noreferrer"&gt;an article on the New York Times’ website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here we have two columns: one wide column and one narrow column. The wider column includes a flex layout with multiple rows of three thumbnails and headlines (let’s call these headline and thumbnail sets “cards”). The narrower column includes a text-based list of links to the most popular stories. As I adjust the size of my browser window to be smaller, the two columns also change; the flex layout contained in the larger column reduces to show multiple rows of two cards instead of three.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F4dl9s6h18daikq6rkyp4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F4dl9s6h18daikq6rkyp4.png" alt="Screenshots of the “More in…” section of a  New York Times article showing the flex layout change the number of cards in a row. " width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(There’s an empty space in both of these screenshots because of my ad blocker. 🙃)&lt;/p&gt;

&lt;p&gt;Currently, this is achieved with media queries. The individual cards are given a &lt;code&gt;max-width&lt;/code&gt; that increases or decreases depending on the viewport’s width in pixels.&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;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;48%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&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;768px&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;32%&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;This works fine here, but what if this flex container of cards had more applications? Maybe a content author could insert our flex container into both narrow and wide columns. Currently, we only have the one media query for a &lt;code&gt;min-width: 768px&lt;/code&gt;, but that would not be enough to make the cards look good in a significantly narrower column. &lt;/p&gt;

&lt;p&gt;And just think if our imaginary stakeholders wanted even more options: one, three, four column layouts that have to fit our flex container. Our edge cases are going to quickly spiral out of control as we’ll have to manually test and write out every possible viewport width combination as a media query. Instead of doing that, though, we can use container queries to scope these variations to the width of the container itself.&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;.card-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;container-type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;48%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@container&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;420px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&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;span class="k"&gt;@container&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;680px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;32%&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;Note that we’re only styling the child &lt;code&gt;.card&lt;/code&gt; selector within the container query. &lt;code&gt;@container&lt;/code&gt; does not allow us to style the container itself. To apply responsive styles to the container element itself, we’ll need to still use &lt;code&gt;@media&lt;/code&gt;.  Technically we could use &lt;em&gt;another&lt;/em&gt; parent container, but if we need this flex container to have a variety of applications, nesting &lt;code&gt;@container&lt;/code&gt; queries would bring us back to the busy work of working out every possible edge case of parent component.&lt;/p&gt;

&lt;p&gt;With the continued popularity of component-based design systems and UI component libraries like Storybook, container queries allow us to be more consistently modular and flexible in our code. &lt;/p&gt;

&lt;h2&gt;
  
  
  container-type
&lt;/h2&gt;

&lt;p&gt;The key to getting a container query to work is adding a &lt;code&gt;container-type&lt;/code&gt; property to the element you wish to enable as a container. This will also allow the container to show up in &lt;a href="https://developer.chrome.com/docs/devtools/css/container-queries/" rel="noopener noreferrer"&gt;Chrome DevTools&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://www.w3.org/TR/2022/WD-css-contain-3-20220818/" rel="noopener noreferrer"&gt;latest working draft&lt;/a&gt;, &lt;code&gt;container-type&lt;/code&gt; can take three potential values:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;normal&lt;/code&gt;: the initial value/assumed default. This means the element will not be treated as a queryable container. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;size&lt;/code&gt;: establishes the element as a query container for size queries on both the inline (horizontal) and block (vertical) axis. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;inline-size&lt;/code&gt;: establishes the element as a query container for size queries on the inline (horizontal) axis. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;inline-size&lt;/code&gt; is the one you’ll probably see the most in early examples, and it’s the one I used in my &lt;a href="https://codepen.io/heyitsstacey/full/rNvaPMG" rel="noopener noreferrer"&gt;codepen&lt;/a&gt;. It works the way you’re probably used to working with media queries where it is relative to the width of the container. &lt;/p&gt;

&lt;h2&gt;
  
  
  container-name
&lt;/h2&gt;

&lt;p&gt;You may find yourself wanting to establish multiple containers on a page with different styles. In this case, you’ll want to use the &lt;code&gt;container-name&lt;/code&gt; property. This takes any string as a value and will allow you to specify which container you’re querying:&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;.card-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;container-type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;container-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;card-container&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@container&lt;/span&gt; &lt;span class="n"&gt;card-container&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;420px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&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 this example, I’ve used the class name as the &lt;code&gt;container-name&lt;/code&gt;, but that is by no means a requirement. It can be any unique, single-word string you need. As for best practices, while it’s still early days, the current draft uses kebob case (dashes) in &lt;a href="https://www.w3.org/TR/css-contain-3/#container-name" rel="noopener noreferrer"&gt;its examples&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Size container features beyond width
&lt;/h2&gt;

&lt;p&gt;In the examples above, I wrote my container queries using a &lt;code&gt;min-width&lt;/code&gt; and pixel value for my size feature, but we’re not limited to that format. Let’s look at this example from the working draft:&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="nt"&gt;main&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;container-type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;container-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;my-page-layout&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.my-component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;container-type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;container-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;my-component-library&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@container&lt;/span&gt; &lt;span class="n"&gt;my-page-layout&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block-size&lt;/span&gt; &lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;12em&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;margin-block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2em&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;span class="k"&gt;@container&lt;/span&gt; &lt;span class="n"&gt;my-component-library&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inline-size&lt;/span&gt; &lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;30em&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;margin-inline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2em&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;Recall that “inline” refers to the horizontal sizing while “block” is the vertical. In the example above, &lt;code&gt;main&lt;/code&gt;—named &lt;code&gt;my-page-layout&lt;/code&gt;—has the container-type of &lt;code&gt;size&lt;/code&gt; (both block and inline) while &lt;code&gt;.my-component&lt;/code&gt;—named &lt;code&gt;my component-library&lt;/code&gt;—has an &lt;code&gt;inline-size&lt;/code&gt; (just inline). Therefore, in their named container queries, &lt;code&gt;@container my-page-layout (block-size &amp;gt; 12em)&lt;/code&gt; will apply with a container height larger than &lt;code&gt;12em&lt;/code&gt;, whereas &lt;code&gt;@container my-component-library (inline-size &amp;gt; 30em)&lt;/code&gt; will apply with a width larger than &lt;code&gt;30em&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;In future iterations, we may be to write size container queries in respect to aspect-ratio as well. &lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;As you may have guessed from multiple references to the working draft, &lt;code&gt;@container&lt;/code&gt; is not universally supported yet. It is available in only the newest version of Chrome and Chromium-based Edge (partially), but is not yet in FireFox or Safari. Keeping an eye on &lt;a href="https://caniuse.com/?search=container-type" rel="noopener noreferrer"&gt;CanIUse.com&lt;/a&gt;, we see support is slowly but surely rolling out, as it’s now in the latest Safari Technology Preview. You will probably find yourself using &lt;code&gt;@media&lt;/code&gt; in most cases for a little while longer, but it’s exciting to see such mainstream progress on its adoption.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Posted late at night (for me) and edited with fresh eyes in the morning; cross-posted to my site.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Hiding Images with Content Warnings in React</title>
      <dc:creator>Stacey</dc:creator>
      <pubDate>Wed, 15 Jun 2022 14:45:10 +0000</pubDate>
      <link>https://dev.to/heyitsstacey/hiding-images-with-content-warnings-in-react-36c9</link>
      <guid>https://dev.to/heyitsstacey/hiding-images-with-content-warnings-in-react-36c9</guid>
      <description>&lt;p&gt;After attending Tori Clark and Keli Sierra Bradley’s &lt;a href="https://www.deque.com/axe-con/sessions/my-trigger-my-choice-ux-for-trigger-and-content-warnings/" rel="noopener noreferrer"&gt;axe-con talk on trigger and content warnings&lt;/a&gt;, I put making a toggle-able content warning for my blog on my to-do list. &lt;/p&gt;

&lt;p&gt;By content warning, I’m envisioning something similar to Instagram’s current implementation. In the screenshot included below, the account belonging to horror magazine &lt;a href="https://www.instagram.com/fangoria/" rel="noopener noreferrer"&gt;Fangoria&lt;/a&gt; has age-gated some of its especially gnarly images. The image is blurred beyond recognition with text overlaying it that lets users know why it is hidden. Lastly, there is a button to click to reveal the image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fyctp59apwvuzkf4kd32f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fyctp59apwvuzkf4kd32f.png" alt="screen grab of a censored photo on Fangoria's Instagram account" width="640" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my past life in academia, I wrote a lot about horror video games, and would like to better integrate that interest into my portfolio. Given that most of my website is about my current experience as a front-end developer, including a warning before the, uh, grosser of that content sounded like a good idea.&lt;/p&gt;

&lt;p&gt;In their talk, Clark and Bradley compared content warnings to wet floor signs: the warning benefits everyone, but some people are more likely to slip than others. I interpreted that to mean, if you have an image you think &lt;em&gt;might&lt;/em&gt; be triggering to someone, it’s best to err on the side of caution and give users the opportunity to opt into seeing it. The worst case is that a user may have to take an extra action to see it, which, I think, is worth the payoff of potentially ruining someone’s day by &lt;em&gt;not&lt;/em&gt; hiding it. I specifically brought up content warnings in terms of hiding horror, but it could have a lot of other, comparatively benign applications such as hiding a spoiler from a popular TV show or respecting culture-specific sensitivities.&lt;/p&gt;

&lt;p&gt;My portfolio currently uses GatsbyJS, so React is going to be the way to go for me, and JSX makes it very easy to hide and show HTML elements inline. That said, this should be relatively easy to adapt to other frameworks like Vue or even vanilla Javascript if we break it down effectively. &lt;/p&gt;

&lt;h2&gt;
  
  
  The elements of our component
&lt;/h2&gt;

&lt;p&gt;Just taking the instagram post as an example, we know we need at least four basic pieces for our component:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;an image&lt;/li&gt;
&lt;li&gt;alt text&lt;/li&gt;
&lt;li&gt;toggle state management&lt;/li&gt;
&lt;li&gt;warning copy&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If we are making this a re-usable React component, we know that at a bare minimum, the image will be different each time. Therefore, we’ll pass the image url and alt text in as props. We may want to start with something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ContentWarning&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;imgSrc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;imgSrc&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Continuing down our list, we know we need a way to manage state, which we can easily use in modern React with the &lt;code&gt;useState&lt;/code&gt; hook. We’ll also go ahead and throw in our warning text.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ContentWarning&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;imgSrc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setShowContent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;imgSrc&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"warning-text"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              This image may contain sensitive content
     &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what all do we need to control with our state? We know we want to disguise the image and show our warning text when &lt;code&gt;showContent&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt;, but we also should be careful to disguise our alt text so that a screenreader user also isn’t inadvertently exposed to something they don’t want to hear. All images &lt;em&gt;must&lt;/em&gt; have an &lt;code&gt;alt&lt;/code&gt; attribute in compliance with &lt;a href="https://www.w3.org/TR/WCAG21/" rel="noopener noreferrer"&gt;WCAG&lt;/a&gt;, but that attribute can be empty—no space, just empty—so we’ll add a ternary function to check for whether &lt;code&gt;showContent&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;. Similarly we’ll use the logical and operator to only display the content warning if &lt;code&gt;showContent&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Fortunately, blurring the image only requires a single line of code in modern CSS! We will similarly only include that if &lt;code&gt;showContent&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ContentWarning&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;imgSrc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setShowContent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; 
                &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;imgSrc&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blur(1.5rem)&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;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"warning-text"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              This image may contain sensitive content
     &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, to manage the state of our content, we need a button for users to click to toggle the image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ContentWarning&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;imgSrc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setShowContent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; 
                &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;imgSrc&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blur(1.5rem)&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;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"warning-text"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              This image may contain sensitive content
     &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
          &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"toggle-button"&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
          &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setShowContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hide&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;Show&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; Image
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;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://dev.to/heyitsstacey/quick-tip-always-include-a-type-on-your-buttons-3cbh"&gt;remember to add a &lt;code&gt;type&lt;/code&gt; to your button, folks!&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting it all together
&lt;/h2&gt;

&lt;p&gt;To use our component, the code would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ContentWarning&lt;/span&gt;
      &lt;span class="na"&gt;imgSrc&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://picsum.photos/id/1025/500/300"&lt;/span&gt;
      &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"an adorable pug sitting upright while wrapped in a blanket in the woods"&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we put that all together and we see our image hiding and showing based on our state… all good! ….Right? &lt;/p&gt;

&lt;p&gt;Actually, there is at least one more step. Remember how I mentioned we also wanted to render the alt text conditionally based on whether the content was hidden or not? In its current implementation, this &lt;em&gt;does&lt;/em&gt; add the alt text back to the page when we show the image, but a screen reader user won't immediately get that new information like a sighted user will when they see the instant visual change. There are a couple ways to solve for this, and I think the simplest solution may be to just wrap our image in a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions" rel="noopener noreferrer"&gt;live region&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ContentWarning&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;imgSrc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setShowContent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;aria-live&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"polite"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt;
            &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blur(1.5rem)&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;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;imgSrc&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"warning-text"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              This image may contain sensitive content
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
          &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"toggle-button"&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
          &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setShowContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hide&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;Show&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; Image
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;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;This way, it will announce the new text after a user hits the toggle button.&lt;/p&gt;

&lt;p&gt;Here’s a &lt;a href="https://codepen.io/heyitsstacey/pen/BaYvver" rel="noopener noreferrer"&gt;Codepen example&lt;/a&gt; with some small style tweaks to make it a little more presentable (don’t worry, the image is an inoffensive and &lt;em&gt;very&lt;/em&gt; cute dog).&lt;/p&gt;

&lt;h2&gt;
  
  
  Potential enhancements
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Global Toggles
&lt;/h3&gt;

&lt;p&gt;On social media platforms like Twitter, users have the option of opting in and out of seeing “media that may contain sensitive content.” We therefore may also want to have a site-wide toggle that will hide or reveal all images on the page. &lt;/p&gt;

&lt;p&gt;To do this: instead of just passing the image url and alt text as props, we would also pass something like &lt;code&gt;globalShowContent&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ContentWarning&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;imgSrc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;globalShowContent&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we still want users to be able to toggle individual images, we would start by setting our component level state as &lt;code&gt;const [showContent, setShowContent] = React.useState(globalShowContent);&lt;/code&gt; to respect the global setting from the jump.&lt;/p&gt;

&lt;h3&gt;
  
  
  Srcset instead of Src
&lt;/h3&gt;

&lt;p&gt;Since we are well into 2022 at this point, you may want to pass in multiple image sources a la &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-srcset" rel="noopener noreferrer"&gt;srcset&lt;/a&gt;, to do this, in addition to passing in a string with &lt;code&gt;imgSrc&lt;/code&gt;, we could pass an array of strings containing our urls and sizes (&lt;code&gt;["https://picsum.photos/id/1025/500/300 x1”, “https://picsum.photos/id/1025/1000/600 x2”]&lt;/code&gt;), and map it in our component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;imgSrc&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
     &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;showContent&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
         &lt;span class="na"&gt;srcSet&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;imgSrcSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imgSrc&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;imgSrc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;As Clark and Bradley called out in their talk, ensuring users can safely access your content is an accessibility issue, and content warnings are a relatively straightforward way to do that. Whether it’s gating potentially-triggering content or just hiding a spoiler, it’s worth putting basic safe guards in place to ensure your users have a smooth, pain-free experience. Hopefully this example proves to be an easy baseline for starting your component.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit to correct typos; cross-posted from my site&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>a11y</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Rebasing in English</title>
      <dc:creator>Stacey</dc:creator>
      <pubDate>Tue, 17 May 2022 12:46:16 +0000</pubDate>
      <link>https://dev.to/heyitsstacey/rebasing-in-english-4178</link>
      <guid>https://dev.to/heyitsstacey/rebasing-in-english-4178</guid>
      <description>&lt;p&gt;A coworker recently explained rebasing in a way that made it make sense to me for the first time: it's just pretending you branched off of better code than you actually did.&lt;/p&gt;

&lt;p&gt;The usual diagram of rebasing looks something like this: &lt;br&gt;
&lt;a href="https://media2.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%2F1zelx6dtur4ur29yo6gr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F1zelx6dtur4ur29yo6gr.gif" alt="a main branch has a feature branch rebased on it, it essentially looks like a straight line that then zig-zags upward" width="500" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is clear to me when I have two branches--a main/master branch and a second branch with my new feature--but that's rarely how a repo is being used. There's usually multiple feature and bug branches being worked on simultaneously--often by different team members. When I'm asked to rebase due to changes made to main, this diagram makes it look destructive and scary. To be clear, it IS destructive in the sense that it fundamentally changes the history of your branch, but the consequences aren’t necessarily as scary as they appear. &lt;/p&gt;

&lt;p&gt;For me at least, I found it helpful to just ignore the diagram and think of it like this: &lt;/p&gt;

&lt;p&gt;First, I made my feature off of main. Meanwhile, someone else made a significant improvement to main--an important bug fix maybe. I could merge main into my branch and leave a paper trail, but if we're confident in these changes, why not keep my commits clean and pretend like they were always there? Rebasing essentially tells my feature branch, hey, let's just act like I was working off of this new and improved main branch all along.&lt;/p&gt;

</description>
      <category>git</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Quick Tip: always include a type on your buttons</title>
      <dc:creator>Stacey</dc:creator>
      <pubDate>Sun, 24 Apr 2022 16:56:05 +0000</pubDate>
      <link>https://dev.to/heyitsstacey/quick-tip-always-include-a-type-on-your-buttons-3cbh</link>
      <guid>https://dev.to/heyitsstacey/quick-tip-always-include-a-type-on-your-buttons-3cbh</guid>
      <description>&lt;p&gt;Did you know the default &lt;code&gt;type&lt;/code&gt; value on a &lt;code&gt;button&lt;/code&gt; element &lt;em&gt;isn’t&lt;/em&gt; “button?” &lt;/p&gt;

&lt;p&gt;To step back for a moment, the &lt;code&gt;button&lt;/code&gt; element was introduced as part of HTML 4 specification in the late 90s—it’s been with us awhile. Previously, if you wanted a submit button on a form, you would use an &lt;code&gt;input&lt;/code&gt; with a &lt;code&gt;type="submit"&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Submit the form"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Increasingly, the button does more than just submit or reset form values. It opens dialogs! Navigates slideshows! All of our favorite things! &lt;/p&gt;

&lt;p&gt;The modern &lt;code&gt;button&lt;/code&gt; element carries over many of the attributes of the original &lt;code&gt;input&lt;/code&gt; spec, including a &lt;code&gt;type&lt;/code&gt; that defines the button’s behavior. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;type&lt;/code&gt; takes three possible values, all of which are fairly self-evident. To quote the &lt;a href="https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element" rel="noopener noreferrer"&gt;HTML Standard spec&lt;/a&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;submit&lt;/code&gt; - “submits the form”&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;reset&lt;/code&gt; - “resets the form”&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;button&lt;/code&gt; - “does nothing”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is great for a number of reasons, especially because it makes it very clear to you or whoever has to read your code after you &lt;em&gt;exactly&lt;/em&gt; what this button does.&lt;/p&gt;

&lt;p&gt;The tricky part comes from when the &lt;code&gt;type&lt;/code&gt; &lt;em&gt;isn’t&lt;/em&gt; set. If we have a button element without a type (&lt;code&gt;&amp;lt;button&amp;gt;My Sample Button&amp;lt;/button&amp;gt;&lt;/code&gt;) or a button with an invalid type value &lt;code&gt;&amp;lt;button type="resete"&amp;gt;My Sample Button with mispelled "type"&amp;lt;/button&amp;gt;&lt;/code&gt;, the state defaults to &lt;code&gt;submit&lt;/code&gt; &lt;em&gt;not&lt;/em&gt; &lt;code&gt;button&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;(except in Internet Explorer, because IE always has to do its own thing)&lt;/p&gt;

&lt;p&gt;This is an easy step to miss, and depending on your project, might not cause any obvious issues. Or it could cause &lt;em&gt;very&lt;/em&gt; obvious issues.&lt;/p&gt;

&lt;p&gt;For example, let’s say you’re building a form and it calls for a dialog with more information. You may put a button trigger for that dialog. If you don’t include a &lt;code&gt;type&lt;/code&gt; on that button, clicking that button will submit the form before the user’s ready! Here’s an &lt;a href="https://codepen.io/heyitsstacey/pen/popmvZz" rel="noopener noreferrer"&gt;extremely basic codepen&lt;/a&gt; example.&lt;/p&gt;

&lt;p&gt;The lesson here, then, is always assign a value to your &lt;code&gt;type&lt;/code&gt;. It makes your code valid, readable, and saves your users headaches.&lt;/p&gt;

</description>
      <category>html</category>
      <category>beginners</category>
    </item>
    <item>
      <title>&lt;details&gt; and &lt;summary&gt;: a native HTML accordion</title>
      <dc:creator>Stacey</dc:creator>
      <pubDate>Fri, 15 Apr 2022 20:16:18 +0000</pubDate>
      <link>https://dev.to/heyitsstacey/and-an-native-html-accordion-5797</link>
      <guid>https://dev.to/heyitsstacey/and-an-native-html-accordion-5797</guid>
      <description>&lt;p&gt;Did you know about &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt;? If you did, great. I’m happy for you. If you--like me--did not, the code looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;details&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;More Information&lt;span class="nt"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
&lt;span class="nt"&gt;&amp;lt;/details&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rendered, it would look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F4rm727wiqdmih36g78p9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F4rm727wiqdmih36g78p9.png" alt="a left-facing arrow with the text “More Information”" width="145" height="40"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click on that “more information” text—either with a mouse or space bar on focus—you’ll see this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fdylxclp0sufdon26vjpq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fdylxclp0sufdon26vjpq.png" alt="The arrow beside “More Information” now points downward toward the now visible “lorem ipsum” text." width="711" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicking “More Information” will hide the expanded text again. &lt;/p&gt;

&lt;p&gt;Essentially, anything you put in &lt;code&gt;summary&lt;/code&gt; becomes a button-like element that, when pressed, displays any children of &lt;code&gt;details&lt;/code&gt; that come immediately after it. You can wrap those adjacent children in a &lt;code&gt;div&lt;/code&gt; for easy styling, but just dumping the text right next to the &lt;code&gt;summary&lt;/code&gt; works just fine. This makes it sound a heck of a lot like the countless custom accordions you’ve no doubt had to make. A native HTML solution is almost always preferred to a custom one, and this one is supported in modern browsers, and its appearance is relatively easy to customize. &lt;/p&gt;

&lt;p&gt;The black arrow renders as a &lt;code&gt;:marker&lt;/code&gt; on &lt;code&gt;summary&lt;/code&gt; in most modern browsers, which is easy to disable with &lt;code&gt;list-style-type: none&lt;/code&gt; and replace with whatever pseudo-class &lt;code&gt;content&lt;/code&gt; or &lt;code&gt;background-image&lt;/code&gt; you choose. The exception, as expected, is Safari, which still uses &lt;code&gt;::-webkit-details-marker&lt;/code&gt;  (&lt;code&gt;summary::webkit-details-marker&lt;/code&gt;). So in order to fully disable the default marker style, you’ll need to do something like this:&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="nt"&gt;summary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;list-style-type&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;span class="nt"&gt;summary&lt;/span&gt;&lt;span class="nd"&gt;::webkit-details-marker&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="nb"&gt;none&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Still pretty painless!&lt;/p&gt;

&lt;p&gt;&lt;code&gt;details&lt;/code&gt; also comes with a handy &lt;code&gt;open&lt;/code&gt; property that appears when the full text is expanded, allowing you to animate your custom marker. &lt;a href="https://codepen.io/heyitsstacey/pen/JjMeXJY" rel="noopener noreferrer"&gt;Here’s a simple, if impractical, example on codepen&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;There’s always a catch. While &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt; are a great, out-of-the-box solution for a lot of projects. There are some exceptions to consider.&lt;/p&gt;

&lt;h3&gt;
  
  
  No IE support
&lt;/h3&gt;

&lt;p&gt;As I’m sure you can guess, this is not available in any version of Internet Explorer. If you still need to support IE11, you’ll need to come up with a custom solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customized animations/transitions
&lt;/h3&gt;

&lt;p&gt;One of the main reasons we end up turning to custom solutions is because of &lt;em&gt;very&lt;/em&gt; specific UI requirements; we often want that hidden text to gracefully slide into view when expanded. Unfortunately, while you can modify the appearance of the marker fairly easily, you won’t be able to do &lt;em&gt;too&lt;/em&gt; much with the actual text reveal transition without some extra Javascript.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessibility considerations
&lt;/h3&gt;

&lt;p&gt;For the most part, this component is fairly accessible out of the box; you’re able to navigate it using your keyboard, with both keyboard and most assistive technology treating the &lt;code&gt;summary&lt;/code&gt; element as a button. However, as &lt;a href="https://www.hassellinclusion.com/blog/accessible-accordions-part-2-using-details-summary/" rel="noopener noreferrer"&gt;Hassel Inclusion discovered&lt;/a&gt; in a test of the element in 2019, the revealed text isn’t always announced correctly by screen readers, so an unsighted user might not know what their button press actually did. A way around this may be adding extra markup and a little Javascript to make the expanded text a live region when it is expanded, or perhaps just move focus on expansion to the new text. At that point, you’re basically making a custom component, though.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;this post was cross-posted from my site&lt;/em&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>snippets</category>
    </item>
    <item>
      <title>VSCode snippet for IE11-only CSS and SCSS</title>
      <dc:creator>Stacey</dc:creator>
      <pubDate>Thu, 31 Mar 2022 10:27:20 +0000</pubDate>
      <link>https://dev.to/heyitsstacey/vscode-snippet-for-ie11-only-css-and-scss-2kn2</link>
      <guid>https://dev.to/heyitsstacey/vscode-snippet-for-ie11-only-css-and-scss-2kn2</guid>
      <description>&lt;p&gt;I’m very grateful that my current employer has chosen to put Internet Explorer 11 out to pasture, but I have not always been so lucky. Even as Microsoft prepares to end support this June, so long as a significant number of users refuse to upgrade, some devs will be forced to support it. A few years ago, I added a snippet for SCSS for projects that still needed the support, and have now adapted it for CSS to make it a little more flexible.&lt;/p&gt;

&lt;p&gt;To use this snippet, add the following to your CSS snippets (on Mac, that’s Code -&amp;gt; Preferences -&amp;gt; User Snippets).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "IE11": {
    "prefix": "IE11",
    "body": [
      " /* rule only parsed by IE11 (╯°□°)╯︵ ┻━┻*/",
      "*::-ms-backdrop, $1 {",
      "$0",
      "}"
    ],
    "description": "IE11 override styles"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if you start typing “ie” in a css file, you should be prompted to choose “IE11” from your snippets, resulting in the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* rule only parsed by IE11 (╯°□°)╯︵ ┻━┻*/
*::-ms-backdrop,  {

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

&lt;/div&gt;



&lt;p&gt;When authoring, your cursor will first appear after the &lt;code&gt;*::-ms-backdrop,&lt;/code&gt; ready to add the selector you want to style (for example, &lt;code&gt;*::-ms-backdrop, .container&lt;/code&gt;). When that’s done, hit tab to enter the curly braces to start adding your styles.&lt;/p&gt;

&lt;p&gt;(If you haven’t authored VS Code snippets before, the &lt;code&gt;$1&lt;/code&gt; and &lt;code&gt;$0&lt;/code&gt; in the snippet denote the tab stops for authoring. &lt;code&gt;$1&lt;/code&gt; is first and &lt;code&gt;$0&lt;/code&gt; is last. &lt;a href="https://code.visualstudio.com/docs/editor/userdefinedsnippets#_tabstops" rel="noopener noreferrer"&gt;See the VSCode docs for more&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;If you want to test out the override itself, &lt;a href="https://codepen.io/heyitsstacey/pen/VwyzVaG" rel="noopener noreferrer"&gt;I’ve set up a codepen&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do this?
&lt;/h2&gt;

&lt;p&gt;Back when we thought IE6 was as bad as it could get, Microsoft supported conditional comments where we could print special messages (“upgrade your browser, you maniac”) or even link browser-specific stylesheets like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!--[if IE 6]&amp;gt;
&amp;lt;link rel="stylesheet" href="i6sux.css"&amp;gt;
&amp;lt;![endif]--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, these were dropped with newer versions of the browser, leaving developers to instead look for pseudo-classes that only exist in Internet Explorer. This is inherently fragile, and not every solution works for every version. In my example, &lt;code&gt;*::-ms-backdrop&lt;/code&gt; seems to work specifically for IE11. If you need to support even older versions of IE, &lt;a href="https://stackoverflow.com/questions/28417056/how-to-target-only-ie-any-version-within-a-stylesheet" rel="noopener noreferrer"&gt;Stackoverflow&lt;/a&gt; is haunted by the ghosts of devs past, all desperate to target whatever the latest version of Internet Explorer was at the time.&lt;/p&gt;

&lt;p&gt;It’s worth noting that usually when I see examples using &lt;code&gt;*::-ms-backdrop&lt;/code&gt;, they are wrapped in a media query like &lt;code&gt;media all and (-ms-high-contrast:none)&lt;/code&gt;. In my experience, that hasn’t been necessary. I think it would also omit users that have high-contrast settings enabled from seeing your fixes, though I have not tested that myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about SCSS?
&lt;/h2&gt;

&lt;p&gt;I primarily used my snippet in SCSS files, so my &lt;em&gt;actual&lt;/em&gt; snippet looks more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "IE11": {
    "prefix": "IE11",
    "body": ["   //rule only parsed by IE11 (╯°□°)╯︵ ┻━┻", "*::-ms-backdrop, &amp;amp; {", "$1", "}"],
    "description": "IE11 override styles"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this being a possible use case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.container {
    display: grid;

     //rule only parsed by IE11 (╯°□°)╯︵ ┻━┻
    *::-ms-backdrop, &amp;amp; {
        display: flex;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are unfamiliar with SCSS, the &lt;code&gt;&amp;amp;&lt;/code&gt; represents a repeat of the parent selector, &lt;code&gt;.container&lt;/code&gt;. This makes it a bit more modular and easier to re-use than just plain CSS. In the example above, it will use &lt;code&gt;display: grid&lt;/code&gt; in modern browsers but &lt;code&gt;display: flex&lt;/code&gt; in Internet Explorer 11, because grid is annoying in IE11.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;If you take nothing from this post, at least take the table-throwing emoticon:&lt;/p&gt;

&lt;p&gt;(╯°□°)╯︵ ┻━┻&lt;/p&gt;

&lt;p&gt;&lt;em&gt;this post was cross-posted from my site&lt;/em&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>scss</category>
      <category>vscode</category>
      <category>snippets</category>
    </item>
    <item>
      <title>axe-con 2022 takeaways: CSS</title>
      <dc:creator>Stacey</dc:creator>
      <pubDate>Tue, 22 Mar 2022 23:04:31 +0000</pubDate>
      <link>https://dev.to/heyitsstacey/axe-con-2022-takeaways-css-2i75</link>
      <guid>https://dev.to/heyitsstacey/axe-con-2022-takeaways-css-2i75</guid>
      <description>&lt;p&gt;This year’s &lt;a href="https://www.deque.com/axe-con/schedule/" rel="noopener noreferrer"&gt;axe-con&lt;/a&gt; featured two talks about new and upcoming CSS changes and their potential impacts on accessibility, &lt;a href="https://noti.st/rachelandrew" rel="noopener noreferrer"&gt;Rachel Andrew&lt;/a&gt;‘s “New CSS with accessibility in mind” and  &lt;a href="https://thinkdobecreate.com/" rel="noopener noreferrer"&gt;Stephanie Eckles&lt;/a&gt;’ "Modern CSS Upgrades To Improve Accessibility.” Both were great and absolutely worth the watch (registering with the con for free gets you access to previous sessions). Here are a few of the key takeaways I noted from the talks.&lt;/p&gt;

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

&lt;p&gt;The &lt;code&gt;contents&lt;/code&gt; value was discussed by &lt;a href="https://noti.st/rachelandrew" rel="noopener noreferrer"&gt;Rachel Andrew&lt;/a&gt; in “New CSS with accessibility in mind.” Supported by modern browsers, &lt;code&gt;display: contents&lt;/code&gt; drops the wrapping “box” from elements to allow the children to inherit the flex behavior of their grandparent. &lt;/p&gt;

&lt;p&gt;Take the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display: flex"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nested-div"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;A direct child div&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display: contents"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;One List Item&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;A Second List Item&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have a div with a class “container” that has two directly nested elements: another div, and an unordered list. If we give the &lt;code&gt;container&lt;/code&gt; a &lt;code&gt;display: flex&lt;/code&gt; and the unordered list the &lt;code&gt;display: contents&lt;/code&gt; property and value, the list items contained therein will appear inline with the nested div as if they were immediate children of the &lt;code&gt;container&lt;/code&gt; div. &lt;/p&gt;

&lt;p&gt;Here’s a &lt;a href="https://codepen.io/heyitsstacey/pen/MWryMZp" rel="noopener noreferrer"&gt;Codepen example&lt;/a&gt; if you’d like to play with it yourself.&lt;/p&gt;

&lt;p&gt;Note that this specifically applies to the &lt;code&gt;display&lt;/code&gt; of the children and not necessarily other properties. If I were to include a style like &lt;code&gt;.container &amp;gt; * { margin-left: 5rem }&lt;/code&gt; the immediate child div would have a margin-left of &lt;code&gt;5rem&lt;/code&gt;, but the more deeply nested &lt;code&gt;li&lt;/code&gt; elements would not.&lt;/p&gt;

&lt;p&gt;From an accessibility perspective, from Andrew’s talk, I learned this was originally implemented incorrectly by browsers where the element was set to &lt;code&gt;display: none&lt;/code&gt; and children were “put back” on the page—but they were all effectively hidden from screen readers.  As of 2020, According to a blog post by &lt;a href="https://adrianroselli.com/2018/02/tables-css-display-properties-and-aria.html" rel="noopener noreferrer"&gt;Adrian Roselli&lt;/a&gt;, this was fixed in Chromium browsers, while Firefox and Safari still had issues when this was applied to tables. The lesson here being that whenever a fun new &lt;code&gt;contents&lt;/code&gt; value is released, check how it is interpreted by assistive technologies to make sure the browser isn’t stripping the element’s role or removing it completely. &lt;/p&gt;

&lt;h2&gt;
  
  
  color-contrast()
&lt;/h2&gt;

&lt;p&gt;The new bit of CSS I was most excited about from the talk was the one with the least amount of support. The functional notation &lt;code&gt;color-contrast()&lt;/code&gt; is currently only implemented in Safari Technology Preview but has awesome potential! It compares one color with a list of other potential colors and picks the one match with the highest contrast. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color-contrast" rel="noopener noreferrer"&gt;MDN Web Docs&lt;/a&gt; give the following example: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;color: color-contrast(wheat vs tan, sienna, #d2691e)&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Here, the color &lt;code&gt;wheat&lt;/code&gt; is compared against a list containing two named colors and a hex value— &lt;code&gt;tan&lt;/code&gt;, &lt;code&gt;sienna&lt;/code&gt; and &lt;code&gt;#d2691e&lt;/code&gt; —where it will ultimately return &lt;code&gt;sienna&lt;/code&gt; as the &lt;code&gt;color&lt;/code&gt; on the element. &lt;/p&gt;

&lt;p&gt;This will be especially helpful when combined with CSS custom properties and the new &lt;code&gt;prefers-color-scheme&lt;/code&gt; media query, also discussed in the talk. &lt;code&gt;prefers-color-scheme&lt;/code&gt; detects the user’s OS preference for a light or dark theme, allowing you to customize your website to accommodate those preferences while still using brand colors. This means you could potentially do something like this in the near future:&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="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#eeb4b3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;--background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#2f242c&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;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--background-color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;color-contrast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--background-color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;vs&lt;/span&gt; &lt;span class="m"&gt;#c179b9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#a42cd6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#502274&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://codepen.io/heyitsstacey/pen/abENevK" rel="noopener noreferrer"&gt;try it on Codepen&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;To test this, you will need to make sure you have Experimental Features → CSS color-contrast() enabled in your Safari Technology Preview. &lt;/p&gt;

&lt;h2&gt;
  
  
  prefers-color-scheme and prefers-contrast vs forced-colors
&lt;/h2&gt;

&lt;p&gt;Touched on above, &lt;code&gt;prefers-color-scheme&lt;/code&gt; is a newer media query supported by most modern browsers that checks for the user’s OS preference for dark or light theme, and allows us to adjust styles based on the users preference. However, as Andrew noted in her talk, just because a user prefers a dark color scheme on their OS does not mean &lt;em&gt;your&lt;/em&gt; dark color scheme will be the most accessible combination for the user, so it is important to give users an option to toggle between your website’s light and dark themes.&lt;/p&gt;

&lt;p&gt;By... contrast, &lt;code&gt;prefers-contrast&lt;/code&gt; checks for the user’s color contrast settings at the OS level. This experimental media feature introduced in Stephanie Eckles’ talk, Modern CSS Upgrades to Improve Accessibility, accepts the values &lt;code&gt;less&lt;/code&gt;, &lt;code&gt;more&lt;/code&gt;, or &lt;code&gt;no-preference&lt;/code&gt; (not set in OS). In her talk, Eckles also cited  &lt;code&gt;custom&lt;/code&gt; , meaning the user set preferences in the OS, though that is not currently listed on &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-contrast" rel="noopener noreferrer"&gt;MDN Web Docs&lt;/a&gt;. These primarily help to serve users with light sensitivity where &lt;code&gt;less&lt;/code&gt; will decrease the contrast and &lt;code&gt;more&lt;/code&gt; will increase the contrast to help users better distinguish details. &lt;/p&gt;

&lt;p&gt;Interestingly, Eckles said that these queries can be chained (once support is more universal, of course). In this case, a user can define a style for someone with a dark color scheme who prefers high contrast like so:&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&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-contrast&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"darkslategray"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"white"&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;On the same token, there is another new media query, &lt;code&gt;forced-colors&lt;/code&gt; which is &lt;a href="https://chromestatus.com/feature/5757293075365888" rel="noopener noreferrer"&gt;meant to specifically check&lt;/a&gt; for Windows’ users High Contrast setting.  It has two potential values: &lt;code&gt;none&lt;/code&gt; or &lt;code&gt;active&lt;/code&gt;, where &lt;code&gt;active&lt;/code&gt; indicates that forced colors mode is active on the user's machine.&lt;/p&gt;

&lt;p&gt;Helpfully, Eckles explained the primary difference between&lt;code&gt;prefers-contrast&lt;/code&gt; and &lt;code&gt;force-colors&lt;/code&gt;:  &lt;code&gt;prefers-contrast&lt;/code&gt; presumes that the user still wants to see your design and colors, where &lt;code&gt;force-colors&lt;/code&gt; requires you to use the user’s set color palette. &lt;/p&gt;

&lt;h2&gt;
  
  
  spacing with &lt;code&gt;min()&lt;/code&gt; and &lt;code&gt;clamp()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Moving back from the experimental to something more applicable in code today, Eckles gave some great tips for harnessing more modern CSS methods for responsive spacing.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;clamp()&lt;/code&gt;, from Eckles’ example, is a great way to control the padding and keep it proportionate at different breakpoints/zoom levels. The example she uses is this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;padding: clamp(1rem, 5%, 1.5rem)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In this example, the padding value will be no smaller than &lt;code&gt;1rem&lt;/code&gt;, no larger than &lt;code&gt;1.5rem&lt;/code&gt;, and maintain &lt;code&gt;5%&lt;/code&gt; as an “ideal.” This saves us the trouble of having to define “pixel-perfect” padding tweaks at every breakpoint to ensure the boxes still look as expected in browser resize.&lt;/p&gt;

&lt;p&gt;Similarly, for spacing between boxes, such as a series of &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; elements, she gives the following example:&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="nt"&gt;section&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;128px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;15vh&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;Full disclosure: math functions like &lt;code&gt;min()&lt;/code&gt; generally make my brain hurt. My rudimentary understanding is that the browser will interpret the lowest of the comma-separated expressions to use when applicable. &lt;a href="http://web.dev" rel="noopener noreferrer"&gt;web.dev&lt;/a&gt; has a great demo of how this can work on &lt;a href="https://codepen.io/una/pen/rNeGNVL" rel="noopener noreferrer"&gt;Codepen&lt;/a&gt;. The tricky bit is that despite most examples using 2, &lt;code&gt;min()&lt;/code&gt; can actually take &lt;em&gt;any&lt;/em&gt; number of arguments, though it gets much harder to parse what is happening with more arguments added. &lt;/p&gt;

&lt;p&gt;For accessibility specifically, the main takeaway here is that as users adjust their zoom or browser window size to accommodate their needs, the CSS will preserve the desired ratio between elements. If we were to instead define margin between sections with a set pixel measurement, the space between elements would appear larger and larger as users zoom, perhaps even pushing elements out of the viewport and thus making users unaware that more content even exists. &lt;/p&gt;

&lt;h2&gt;
  
  
  Take more away
&lt;/h2&gt;

&lt;p&gt;While these were the new tricks that arguably blew my mind the most, these are absolutely not the end all be all of either talk. I highly recommend catching the recordings if you can. As of writing, you can still &lt;a href="https://www.deque.com/axe-con/" rel="noopener noreferrer"&gt;register for free&lt;/a&gt; even though the live event has passed, and view these sessions (as well as some great sessions from 2021!)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;this post was cross-posted from my site and edited to fix typos&lt;/em&gt;&lt;/p&gt;

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