<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Styled-Components on blog.iankulin.com</title><link>https://blog.iankulin.com/tags/styled-components/</link><description>Recent content in Styled-Components on blog.iankulin.com</description><generator>Hugo</generator><language>en-AU</language><lastBuildDate>Fri, 12 Jan 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.iankulin.com/tags/styled-components/index.xml" rel="self" type="application/rss+xml"/><item><title>CSS for React Components</title><link>https://blog.iankulin.com/css-for-react-components/</link><pubDate>Fri, 12 Jan 2024 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/css-for-react-components/</guid><description>&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-12-27-at-3.30.32-pm.jpg" alt=""&gt;
&lt;em&gt;Subscribe to my UX design course 😉&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you think back to HTML as being a document with headings and paragraphs and other semantic bits, it made a lot of sense to have the styles (expressed as CSS) separate to the document. This allows us to change the styles without touching the document - perhaps the user wanted a dark theme, needed the text bigger for accessibility, or perhaps the document was being consumed in some other way - for example a screen reader - so the styles were superfluous.&lt;/p&gt;
&lt;p&gt;In tension to this idea, is the idea that all the code related to a single thing should be encapsulated in one place. This is why we invented object orientated programming - we are creating such huge software systems that for a human to be able to maintain them, they need broken down into chunks that can be fully held in mind while we are working on them. Also, when we are talking about a modern single page application, we&amp;rsquo;ve come a long way from thinking of a web &amp;lsquo;page&amp;rsquo; as being a document to be passively consumed.&lt;/p&gt;
&lt;p&gt;Since the point of React is to create reusable &amp;lsquo;components&amp;rsquo; where the JS and HTML are written together, it&amp;rsquo;s reasonable to wonder if perhaps the CSS shouldn&amp;rsquo;t be in there too.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at a few different approaches to managing styles for our components in React.&lt;/p&gt;
&lt;h3 id="old-style-global"&gt;Old Style Global&lt;/h3&gt;
&lt;p&gt;Most times when I&amp;rsquo;m writing vanilla JS, if I&amp;rsquo;m not leveraging off &lt;a href="https://picocss.com/"&gt;Pico&lt;/a&gt; or &lt;a href="https://getbootstrap.com/"&gt;Bootstrap&lt;/a&gt; I have a single site-wide &lt;code&gt;styles.css&lt;/code&gt; file. Obviously this is going to be an option for a React app too. We&amp;rsquo;d just link it from the index.html in the root of our folder. Job&amp;rsquo;s a goodun.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.iankulin.com/images/screen-shot-2023-12-27-at-3.27.51-pm.png"&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-12-27-at-3.27.51-pm.png" width="1000" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The most common downside of this approach, that I come across, is that I change the rest of the HTML through the various iterations, but never clean up the CSS. So I get left with bits of CSS that I&amp;rsquo;m not sure if they are being used somewhere - so I&amp;rsquo;m not brave enough to delete them because my UX testing is not good enough, so those fragments just end up sitting around forever.&lt;/p&gt;
&lt;h3 id="old-style-local"&gt;Old Style local&lt;/h3&gt;
&lt;p&gt;The first CSS we ever wrote was just stuffed in the HTML in style tags, and of course that&amp;rsquo;s still an option. We can use variables to help with the readability, and end up with something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;function Card&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;props&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; CardProps&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; cardStyles&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; React&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;CSSProperties &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; width&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;120px&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; boxShadow&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;0 4px 8px 0 rgba(0, 0, 0, 0.2)&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; textAlign&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;center&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; backgroundColor&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;cornsilk&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; margin&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;10px&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; padding&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;10px&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; transform&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;scale(1)&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; transition&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;transform 0.3s&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;};&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; pictureStyles&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; React&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;CSSProperties &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; width&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;100px&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; height&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;150px&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; margin&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;auto&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; borderRadius&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;50%&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; border&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;2px solid #000&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;};&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; nameStyles&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; React&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;CSSProperties &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; color&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;black&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; fontSize&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#a3be8c"&gt;&amp;#39;18px&amp;#39;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#eceff4"&gt;};&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;return&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;&amp;lt;&lt;/span&gt;div style&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;cardStyles&lt;span style="color:#eceff4"&gt;}&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;&amp;lt;&lt;/span&gt;img style&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;pictureStyles&lt;span style="color:#eceff4"&gt;}&lt;/span&gt; src&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;props&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;image&lt;span style="color:#eceff4"&gt;}&lt;/span&gt; alt&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;props&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;}&lt;/span&gt; width&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;&lt;span style="color:#b48ead"&gt;100&lt;/span&gt;&lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;&amp;lt;&lt;/span&gt;p style&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;nameStyles&lt;span style="color:#eceff4"&gt;}&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;props&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;}&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;&amp;lt;/&lt;/span&gt;p&lt;span style="color:#81a1c1"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;&amp;lt;/&lt;/span&gt;div&lt;span style="color:#81a1c1"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;);}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Initially, this seemed like a good solution, but there&amp;rsquo;s a few bumps involved. The first is that, or course, this is not real CSS. You can see from the type that TypeScript forced me to use (React.CSSProperties) that these are React types that will get turned into CSS at some distant time in the future. Because of this, there are some oddities - my muscle memory wants to type the CSS property names like &lt;code&gt;box-shadow&lt;/code&gt;, but for this they need to be camel case.&lt;/p&gt;
&lt;p&gt;The next issue of &amp;lsquo;it&amp;rsquo;s not actually CSS&amp;rsquo; was when I wanted to do my hover effect for the cards. In CSS this is just:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.card:hover { transform: scale(1.05); background-color: lightgoldenrodyellow;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If I want to do that with inline styles, I need to capture the MouseEnter and MouseLeave events for the card, then swap the inline styles in and out in code. Ain&amp;rsquo;t nobody got the time for that.&lt;/p&gt;
&lt;h3 id="css--component-libraries"&gt;CSS &amp;amp; Component Libraries&lt;/h3&gt;
&lt;p&gt;A common and appealing answer to inline styles is to use CSS libraries such as BootStrap, TailWind etc. As well as allowing you to add complex styles into JSX with short memorable tags, they often enforce a design aesthetic without the developer having to put much thought into it. Since I have minimal design skills, that&amp;rsquo;s an appealing option.&lt;/p&gt;
&lt;p&gt;Taking this a step further are component are React component libraries such as &lt;a href="https://chakra-ui.com/"&gt;chakra&lt;/a&gt;, &lt;a href="https://mui.com/"&gt;Material UI&lt;/a&gt;, and &lt;a href="https://ant.design/components/overview"&gt;Ant&lt;/a&gt;. With these systems, you get styled components (that can be modified) that follow a unified design - you&amp;rsquo;re not really thinking of CSS but at a high level of abstraction.&lt;/p&gt;
&lt;h3 id="componentcss"&gt;component.css&lt;/h3&gt;
&lt;p&gt;I guess the default (since it&amp;rsquo;s generated like this in the create-app step) way of managing CSS closer to our components is to have a .CSS file for each component. This overcomes the &amp;lsquo;cleaning up&amp;rsquo; problem described above. If I&amp;rsquo;m deleting the NavBar component from this project, I can safely eliminate the NavBar.css file at the same time.&lt;/p&gt;
&lt;p&gt;The component CSS file is just imported at the top of the component file.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.iankulin.com/images/screen-shot-2023-12-27-at-3.59.14-pm.png"&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2023-12-27-at-3.59.14-pm.png" width="1000" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you build an app with the CSS in component.css files like this, all the CSS is combined into a single CSS file by the bundler. This raises the possibility of naming conflicts leading the hard to track down problems later. To avoid this I tend to use the component name as a class name and use that to tightly scope the CSS to avoid it bleeding out into other elements.&lt;/p&gt;
&lt;h3 id="modules"&gt;Modules&lt;/h3&gt;
&lt;p&gt;A bit fancier approach is to use CSS modules. This is somewhat similar to the component CSS files described above. Our CSS files have to be renamed to end in &lt;code&gt;.module.css&lt;/code&gt;, then in the code where you normally insert the class names, you use the class names from the styles library:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import styles from &lt;span style="color:#a3be8c"&gt;&amp;#34;./Card.module.css&amp;#34;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; props &lt;span style="color:#81a1c1;font-weight:bold"&gt;for&lt;/span&gt; cardinterface CardProps &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; name&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; string&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; image&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; string&lt;span style="color:#eceff4"&gt;;}&lt;/span&gt;function Card&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;props&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; CardProps&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;return&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;&amp;lt;&lt;/span&gt;div className&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;styles&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;card&lt;span style="color:#eceff4"&gt;}&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;&amp;lt;&lt;/span&gt;img className&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;styles&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;picture&lt;span style="color:#eceff4"&gt;}&lt;/span&gt; src&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;props&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;image&lt;span style="color:#eceff4"&gt;}&lt;/span&gt; alt&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;props&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;}&lt;/span&gt; width&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;&lt;span style="color:#b48ead"&gt;100&lt;/span&gt;&lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;&amp;lt;&lt;/span&gt;p className&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;styles&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;}&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;props&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;}&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;&amp;lt;/&lt;/span&gt;p&lt;span style="color:#81a1c1"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;&amp;lt;/&lt;/span&gt;div&lt;span style="color:#81a1c1"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;);}&lt;/span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;export&lt;/span&gt; default Card&lt;span style="color:#eceff4"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Those class names match the CSS:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.card { width: 120px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); text-align: center; background-color: cornsilk; margin: 10px; padding: 10px; /* tilt and enlarge on mouseover */ transform: scale(1); transition: transform 0.3s;}.card:hover { transform: scale(1.05); background-color: lightgoldenrodyellow;}.name { font-size: 18px; color: black;}.picture { width: 100px; height: 150px; margin: auto; border-radius: 50%; border: 2px solid black;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The advantage of using modules, is that you now do &lt;em&gt;not&lt;/em&gt; have worry about name clashes. If I build the app and have a look in the generated CSS file, you can see how that works:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;._card_j2a8o_2 { width: 120px; box-shadow: 0 4px 8px #0003; text-align: center; background-color: #fff8dc; margin: 10px; padding: 10px; transform: scale(1); transition: transform 0.3s;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;All the generated CSS has unique class names created for it! Presumably these match the ones being used in the JSX, and this explains why you need to use the &lt;code&gt;styles.&lt;/code&gt; names in your components.&lt;/p&gt;
&lt;h3 id="styled-components"&gt;Styled Components&lt;/h3&gt;
&lt;p&gt;There are several libraries that tackle the issue of what to do about CSS in React. One of the more popular ones is &lt;code&gt;Styled Components&lt;/code&gt;. How this works is that you define a base component with some styles in it (with a weird backticky syntax), then build your own components from the styled one. It makes more sense when you see it than my written explanation.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import styled from &lt;span style="color:#a3be8c"&gt;&amp;#34;styled-components&amp;#34;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; StyledDiv &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; styled&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;div&lt;span style="color:#bf616a"&gt;`&lt;/span&gt; width&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#b48ead"&gt;120&lt;/span&gt;px&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; box&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;shadow&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#b48ead"&gt;0&lt;/span&gt; &lt;span style="color:#b48ead"&gt;4&lt;/span&gt;px &lt;span style="color:#b48ead"&gt;8&lt;/span&gt;px &lt;span style="color:#b48ead"&gt;0&lt;/span&gt; rgba&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;0&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#b48ead"&gt;0&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#b48ead"&gt;0&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#b48ead"&gt;0.2&lt;/span&gt;&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; text&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;align&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; center&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; background&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;color&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; cornsilk&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; margin&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#b48ead"&gt;10&lt;/span&gt;px&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; padding&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#b48ead"&gt;10&lt;/span&gt;px&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; transform&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; scale&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;1&lt;/span&gt;&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; transition&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; transform &lt;span style="color:#b48ead"&gt;0.3&lt;/span&gt;s&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;:&lt;/span&gt;hover &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; transform&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; scale&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;1.05&lt;/span&gt;&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; background&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;color&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; lightgoldenrodyellow&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt;&lt;span style="color:#bf616a"&gt;`&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; StyledImage &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; styled&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;img&lt;span style="color:#bf616a"&gt;`&lt;/span&gt; width&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#b48ead"&gt;100&lt;/span&gt;px&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; height&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#b48ead"&gt;150&lt;/span&gt;px&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; margin&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; auto&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; border&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;radius&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#b48ead"&gt;50&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;%&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; border&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#b48ead"&gt;2&lt;/span&gt;px solid black&lt;span style="color:#eceff4"&gt;;&lt;/span&gt;&lt;span style="color:#bf616a"&gt;`&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; StyledP &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; styled&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;p&lt;span style="color:#bf616a"&gt;`&lt;/span&gt; font&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;size&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#b48ead"&gt;18&lt;/span&gt;px&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; color&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; black&lt;span style="color:#eceff4"&gt;;&lt;/span&gt;&lt;span style="color:#bf616a"&gt;`&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;//&lt;/span&gt; props &lt;span style="color:#81a1c1;font-weight:bold"&gt;for&lt;/span&gt; cardinterface CardProps &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; name&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; string&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; image&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; string&lt;span style="color:#eceff4"&gt;;}&lt;/span&gt;function Card&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;props&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; CardProps&lt;span style="color:#eceff4"&gt;)&lt;/span&gt; &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; &lt;span style="color:#81a1c1;font-weight:bold"&gt;return&lt;/span&gt; &lt;span style="color:#eceff4"&gt;(&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;&amp;lt;&lt;/span&gt;StyledDiv className&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#34;card&amp;#34;&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;&amp;lt;&lt;/span&gt;StyledImage className&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#34;picture&amp;#34;&lt;/span&gt; src&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;props&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;image&lt;span style="color:#eceff4"&gt;}&lt;/span&gt; alt&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;props&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;}&lt;/span&gt; width&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;&lt;span style="color:#b48ead"&gt;100&lt;/span&gt;&lt;span style="color:#eceff4"&gt;}&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;/&amp;gt;&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;&amp;lt;&lt;/span&gt;StyledP className&lt;span style="color:#81a1c1"&gt;=&lt;/span&gt;&lt;span style="color:#a3be8c"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;{&lt;/span&gt;props&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;name&lt;span style="color:#eceff4"&gt;}&lt;/span&gt;&lt;span style="color:#81a1c1"&gt;&amp;lt;/&lt;/span&gt;StyledP&lt;span style="color:#81a1c1"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;&amp;lt;/&lt;/span&gt;StyledDiv&lt;span style="color:#81a1c1"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;);}&lt;/span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;export&lt;/span&gt; default Card&lt;span style="color:#eceff4"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you don&amp;rsquo;t mind more dependencies, this is a great solution - I like the clarity of the philosophy of creating styled versions of regular elements as React elements, then using them as the building blocks of our new component. All the CSS attributes you&amp;rsquo;ve learned are still there.&lt;/p&gt;
&lt;p&gt;The only thing I needed to look up was how to deal with my hover. In the CSS this had been:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.card { width: 120px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); text-align: center; background-color: cornsilk; margin: 10px; padding: 10px; transform: scale(1); transition: transform 0.3s;}.card:hover { transform: scale(1.05); background-color: lightgoldenrodyellow;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which had to be translated into this with the &amp;amp; syntax:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#81a1c1;font-weight:bold"&gt;const&lt;/span&gt; StyledDiv &lt;span style="color:#81a1c1"&gt;=&lt;/span&gt; styled&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;div&lt;span style="color:#bf616a"&gt;`&lt;/span&gt; width&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#b48ead"&gt;120&lt;/span&gt;px&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; box&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;shadow&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#b48ead"&gt;0&lt;/span&gt; &lt;span style="color:#b48ead"&gt;4&lt;/span&gt;px &lt;span style="color:#b48ead"&gt;8&lt;/span&gt;px &lt;span style="color:#b48ead"&gt;0&lt;/span&gt; rgba&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;0&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#b48ead"&gt;0&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#b48ead"&gt;0&lt;/span&gt;&lt;span style="color:#eceff4"&gt;,&lt;/span&gt; &lt;span style="color:#b48ead"&gt;0.2&lt;/span&gt;&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; text&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;align&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; center&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; background&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;color&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; cornsilk&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; margin&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#b48ead"&gt;10&lt;/span&gt;px&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; padding&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; &lt;span style="color:#b48ead"&gt;10&lt;/span&gt;px&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; transform&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; scale&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;1&lt;/span&gt;&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; transition&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; transform &lt;span style="color:#b48ead"&gt;0.3&lt;/span&gt;s&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#eceff4"&gt;:&lt;/span&gt;hover &lt;span style="color:#eceff4"&gt;{&lt;/span&gt; transform&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; scale&lt;span style="color:#eceff4"&gt;(&lt;/span&gt;&lt;span style="color:#b48ead"&gt;1.05&lt;/span&gt;&lt;span style="color:#eceff4"&gt;);&lt;/span&gt; background&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;color&lt;span style="color:#eceff4"&gt;:&lt;/span&gt; lightgoldenrodyellow&lt;span style="color:#eceff4"&gt;;&lt;/span&gt; &lt;span style="color:#eceff4"&gt;}&lt;/span&gt;&lt;span style="color:#bf616a"&gt;`&lt;/span&gt;&lt;span style="color:#eceff4"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So - lots of options for dealing with CSS in React. I haven&amp;rsquo;t written much, so I&amp;rsquo;m not sure what my personal preference is. styled-components is definitely the most elegant of the approaches I&amp;rsquo;ve looked at here, but I&amp;rsquo;m a dependency calorie counter so my natural inclination is look elsewhere. The CSS file for each component seems like the next best system - I like that there&amp;rsquo;s no special hooks in the JSX besides the class names I would have used in ordinary HTML, but then you have the risk of name clashes. They can be avoided with the modules - but I am sort of used to dealing with that anyway.&lt;/p&gt;</description></item></channel></rss>