<?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: Steve Meisner</title>
    <description>The latest articles on Forem by Steve Meisner (@herudea).</description>
    <link>https://forem.com/herudea</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%2F63114%2F6ace7622-4b5f-4313-9bc6-45e700ffe95a.jpeg</url>
      <title>Forem: Steve Meisner</title>
      <link>https://forem.com/herudea</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/herudea"/>
    <language>en</language>
    <item>
      <title>Power up SVGs with React and CSS</title>
      <dc:creator>Steve Meisner</dc:creator>
      <pubDate>Sun, 04 Dec 2022 13:26:58 +0000</pubDate>
      <link>https://forem.com/thegnarco/power-up-svgs-with-react-and-css-5i</link>
      <guid>https://forem.com/thegnarco/power-up-svgs-with-react-and-css-5i</guid>
      <description>&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/SVG" rel="noopener noreferrer"&gt;SVGs&lt;/a&gt; (scalable vector graphics) may be old news, but we use them in modern development stacks all of the time. Our device displays have increasingly more pixels, and SVGs can scale infinitely while staying crisp and clean. Similar to HTML, the SVG standard is based on XML and provides a way to describe shapes and paths with markup.&lt;/p&gt;

&lt;p&gt;While there are plenty of ways to use an SVG, we’ll focus on how to use them in small ways to enhance a user's experience. We can provide feedback to users as they interact with our applications by updating the state of SVG attributes, and by using CSS to transition these changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Import an SVG in React
&lt;/h2&gt;

&lt;p&gt;When it's time to use an SVG in a React project, I always find myself searching for how to import the SVG file into my React context. There is more than one way to do this, and I always need the reminder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create React App
&lt;/h3&gt;

&lt;p&gt;Create React App (CRA) currently ships with an SVG logo. It’s imported and used as the &lt;code&gt;src&lt;/code&gt; value for an image element.&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;logo&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;./logo.svg&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;logo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App-logo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;logo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is another way to &lt;a href="https://create-react-app.dev/docs/adding-images-fonts-and-files/" rel="noopener noreferrer"&gt;import an SVG&lt;/a&gt; in Create React App, though. We can import the SVG as a &lt;a href="https://github.com/facebook/create-react-app/blob/d960b9e38c062584ff6cfb1a70e1512509a966e7/packages/react-scripts/lib/react-app.d.ts#L47-L56" rel="noopener noreferrer"&gt;&lt;code&gt;ReactComponent&lt;/code&gt;&lt;/a&gt;. This is because CRA leverages &lt;a href="https://react-svgr.com/" rel="noopener noreferrer"&gt;SVGR&lt;/a&gt; to process SVGs.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ReactComponent&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ReactLogo&lt;/span&gt; &lt;span class="p"&gt;}&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;./logo.svg&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ReactLogo&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;App-logo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;logo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the SVG in this way, we can leverage &lt;a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/29216607f433cbb900acdcf4a0e4ea69e9db5376/types/vhtml/index.d.ts#L1190" rel="noopener noreferrer"&gt;SVGAttributes&lt;/a&gt;, and &lt;code&gt;className&lt;/code&gt; as props.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vanilla React
&lt;/h3&gt;

&lt;p&gt;Outside of Create React App, we have a few options when importing our SVG. We can use SVGR to generate a Component or add SVGR to our webpack configuration so that we can import SVGs in a similar way as the above CRA example. Alternatively, we can create a simple component that returns our SVG.&lt;/p&gt;

&lt;p&gt;An SVG as a Component becomes a handy tool that can be tied to our application state just like anything else.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: Animating an SVG
&lt;/h3&gt;

&lt;p&gt;When building an interface, we often want to give the user feedback when they perform an action, and we can use an SVG to enhance this process.&lt;/p&gt;

&lt;p&gt;In this example, we will create an SVG that represents the checked and unchecked states of a check box icon and use CSS to transition between them. There are many SVG resources available for free, but it often makes sense to roll our own. We used Adobe Illustrator to create an SVG with two simple shapes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&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%2Fnvdzgc9q0l66fll1rbcu.png" alt="SVG Checkbox 1"&gt;&lt;/td&gt;
&lt;td&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%2Fm9uuvo3rpep3te8uz9vj.png" alt="SVG Checkbox 2"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We intentionally broke our checkbox path to have an end and a beginning. This is helpful because it allows us to easily animate &lt;em&gt;from&lt;/em&gt; and &lt;em&gt;to&lt;/em&gt; a particular location.&lt;/p&gt;

&lt;p&gt;An SVG may often contain extra information we don’t need, so it's good to see if it can be simplified before using it. After we have our SVG file, we can use something like &lt;a href="https://jakearchibald.github.io/svgomg/" rel="noopener noreferrer"&gt;SVGOMG&lt;/a&gt; to optimize and clean up our SVGs.&lt;/p&gt;

&lt;p&gt;Now that we have a trimmed-down file, we can describe it with classes and other accessible information. We're using &lt;a href="https://www.thegnar.com/blog/gnarly-learnings-from-july-2022" rel="noopener noreferrer"&gt;&lt;code&gt;color="currentColor"&lt;/code&gt;&lt;/a&gt; which lets the SVG inherit the color of its parent element.&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;svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="Checkbox"&amp;gt;
  &amp;lt;path class="Checkbox-Box" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M19.01 2C20.66 2 22 3.34 22 5v14.01c0 1.65-1.34 2.99-2.99 2.99H5a3 3 0 0 1-3-2.99V5c0-1.65 1.34-3 3-3h13.76" /&amp;gt;
  &amp;lt;path class="Checkbox-Checkmark" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M7 10.55 11.09 15 22.5 2.5" /&amp;gt;
&amp;lt;/svg&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use CSS to describe how we want the checkbox to behave in “checked” and “unchecked” states. We’ll rely heavily on &lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray" rel="noopener noreferrer"&gt;&lt;code&gt;stroke-dasharray&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset" rel="noopener noreferrer"&gt;&lt;code&gt;stroke-dashoffset&lt;/code&gt;&lt;/a&gt;.  Let’s start by setting up the elements to look “unchecked” by default. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;stroke-dasharray&lt;/code&gt; property instructs the stroke to be dashed instead of solid, and sets how long the dashes and gaps should be. We’re setting the &lt;code&gt;.Checkbox-Box&lt;/code&gt; to have dashes that are long enough to make the box look whole. &lt;/p&gt;

&lt;p&gt;For the &lt;code&gt;.Checkbox-Checkmark&lt;/code&gt;, we make the &lt;code&gt;stroke-dasharray&lt;/code&gt; long enough to account for the shape, and then use &lt;code&gt;stroke-dashoffset&lt;/code&gt; to move the dashed stroke along the path to reveal the empty space in between the dashes instead of a dash mark. This makes the checkmark look absent and prepares it to be revealed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.Checkbox {
  stroke-width: 2px;

  &amp;amp;-Box {
    stroke-dasharray: 86;
    stroke-dashoffset: 0;
    transition:
      color 0.12s ease-out,
      stroke-dasharray 0.12s ease-out,
      stroke-dashoffset 0.12s ease-out;
  }

  &amp;amp;-Checkmark {
    stroke-dasharray: 23;
    stroke-dashoffset: 23;
    transition:
      color 0.12s ease-out,
      stroke-dashoffset 0.12s ease-out;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s add styles for the “checked” state. When the &lt;code&gt;Checkbox__checked&lt;/code&gt; class is present, we change the &lt;code&gt;stroke-dasharray&lt;/code&gt; and &lt;code&gt;stroke-dashoffset&lt;/code&gt; values for our paths.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.Checkbox-Box&lt;/code&gt; gets a smaller &lt;code&gt;stroke-dasharray&lt;/code&gt; and a negative &lt;code&gt;stroke-dashoffset&lt;/code&gt; value. This gives the appearance of the top-right corner opening up. The &lt;code&gt;.Checkbox-Checkmark&lt;/code&gt; gets a &lt;code&gt;stroke-dashoffset&lt;/code&gt; of 0, which will give the appearance of it being drawn.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.Checkbox {
  …

  &amp;amp;__checked {
    .Checkbox-Box {
      stroke-dasharray: 60;
      stroke-dashoffset: -11;
    }

    .Checkbox-Checkmark {
      stroke-dashoffset: 0;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These attributes could be set on the SVG elements themselves, but we can add a transition to those values if we bring them into CSS. Check out the finished result:&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%2F6doblkfk5lk4l4uojzjs.gif" 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%2F6doblkfk5lk4l4uojzjs.gif" alt="Checkbox animation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This approach can accomplish a lot with a small amount of code, but it’s especially effective for small visual changes and user feedback. If we have a more complex visual requirement, we may consider reaching for &lt;a href="https://greensock.com/" rel="noopener noreferrer"&gt;Greensock&lt;/a&gt;, &lt;a href="https://lottiefiles.com/" rel="noopener noreferrer"&gt;Lottie&lt;/a&gt;, or &lt;a href="https://barba.js.org/" rel="noopener noreferrer"&gt;Barba&lt;/a&gt; instead.&lt;/p&gt;

&lt;p&gt;There are endless possibilities here, so have fun bringing your own SVGs to life with React and CSS!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Learn more about how The Gnar builds &lt;a href="https://www.thegnar.com/software-development/react-development-js" rel="noopener noreferrer"&gt;React applications&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
