<?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: Vojtěch Vidra</title>
    <description>The latest articles on DEV Community by Vojtěch Vidra (@vojtechvidra).</description>
    <link>https://dev.to/vojtechvidra</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%2F161905%2Fd499faf8-0e28-4631-bbc2-b325806c3fba.jpg</url>
      <title>DEV Community: Vojtěch Vidra</title>
      <link>https://dev.to/vojtechvidra</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vojtechvidra"/>
    <language>en</language>
    <item>
      <title>Product adoption tools suck so me and my homies built Flows</title>
      <dc:creator>Vojtěch Vidra</dc:creator>
      <pubDate>Wed, 03 Dec 2025 10:28:29 +0000</pubDate>
      <link>https://dev.to/vojtechvidra/product-adoption-tools-suck-so-me-and-my-homies-built-flows-2ip9</link>
      <guid>https://dev.to/vojtechvidra/product-adoption-tools-suck-so-me-and-my-homies-built-flows-2ip9</guid>
      <description>&lt;p&gt;If you’ve ever tried building onboarding or product adoption with Appcues, Chameleon, Userflow, WalkMe, or Usetiful, you’ve probably hit the same two problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Everything is rendered with JavaScript overlays&lt;/li&gt;
&lt;li&gt;Customization is a nightmare&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A little backstory:&lt;/p&gt;

&lt;p&gt;When I was choosing an onboarding tool for my previous project, nothing matched what I needed. So I had to build my own. With help from IntroJS I built onboarding solution that I needed: Tooltips, Modals, custom CSS, waiting for interactions, and saving the state into the database. It worked… but it took way more time than it should have, and any change required a redeploy.&lt;/p&gt;

&lt;p&gt;This made me realize: there’s no product-adoption tool made for developers and designers.. So me and my friends started building Flows with a simple philosophy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optional built-in components that get the basics right&lt;/li&gt;
&lt;li&gt;Or use it headless - bring your own components&lt;/li&gt;
&lt;li&gt;SDK for React and JS (supports Vue, Angular, Svelte or any other JS framework)&lt;/li&gt;
&lt;li&gt;Support for floating and inline elements&lt;/li&gt;
&lt;li&gt;Make changes without redeploying&lt;/li&gt;
&lt;li&gt;Fast, lightweight, and predictable&lt;/li&gt;
&lt;li&gt;Fair PAYG pricing with free tier&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now back to the issues and how we’re solving them:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Rendering&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most tools inject UI with JavaScript and target elements using selectors. This limits them to floating UI (tooltips, popups, dialogs). The ones that offer “inline” elements do it with brittle selectors, layout shift, and generic blocks that never really match your product.&lt;/p&gt;

&lt;p&gt;Flows fixes this with a simple “portal” component  that renders the elements directly where you need, with an optional placeholder to avoid layout shift. And floating components are supported as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Customization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good design language isn’t optional anymore, it’s need for people to find your product interesting. That’s why customizing brand colors doesn’t cut it and spending development time on the whole CSS rewrite isn’t smart.&lt;/p&gt;

&lt;p&gt;With Flows you can use your own components. Import them into Flows SDK, define the props in our editor and use them in the workflows. Anyone editing the content has clear visibility into the structure of each component and what each field is used for.&lt;/p&gt;

&lt;p&gt;I’d love any feedback since we’re just getting it out there, thanks!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Color formats on the Web</title>
      <dc:creator>Vojtěch Vidra</dc:creator>
      <pubDate>Tue, 20 Dec 2022 08:15:02 +0000</pubDate>
      <link>https://dev.to/vojtechvidra/color-formats-on-the-web-3j78</link>
      <guid>https://dev.to/vojtechvidra/color-formats-on-the-web-3j78</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;In the world of digital design, color plays a crucial role in creating visually appealing and effective websites and applications. One important aspect of using color on the web is understanding the different color formats available and how to use them effectively. In this blog post, we will explore the different color formats used on the web and discuss when and how to use each one. Whether you are a web designer, developer, or just interested in the technical aspects of color on the web, this post will provide a useful overview of the topic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The difference between color space and color model
&lt;/h2&gt;

&lt;p&gt;Before we dive deep into the world of colors, it's important to establish some key terms. In this article, we'll be discussing color models and color spaces. These two concepts are often used interchangeably, but they are not the same thing.&lt;/p&gt;

&lt;p&gt;A color model is a mathematical system for representing colors in a way that is independent of any specific physical medium. For example, RGB, HSL, and CMYK are all color models.&lt;/p&gt;

&lt;p&gt;On the other hand, a color space is a specific set of colors that can be reproduced on a particular medium, such as a computer screen or printer. It maps the color descriptions provided by a color model to actual, reproducible colors. For instance, sRGB and AdobeRGB are two different color spaces that both use the RGB color model, but the exact same RGB value (such as &lt;code&gt;rgb(87, 60, 250)&lt;/code&gt;) may look slightly different in each color space.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hex
&lt;/h2&gt;

&lt;p&gt;Color space: &lt;strong&gt;sRGB&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hexadecimal notation is a widely used method for representing RGB colors on the web. Despite its popularity, it has limitations due to the constraints of the sRGB color space. Until support for LCH/LAB color space becomes more widespread, hexadecimal notation will remain the most commonly used method. One of the main advantages of hexadecimal notation is its compactness, which can help keep your CSS files short and concise.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hex supports alpha channel
&lt;/h3&gt;

&lt;p&gt;Did you know that hexadecimal notation can be written in a 4- or 8-character format to include an alpha channel? For example, &lt;code&gt;#FF000088&lt;/code&gt; and &lt;code&gt;#F008&lt;/code&gt; both represent red with 53% opacity. When it comes to browser support for this format, the news is good: aside from IE11, most modern browsers support it. You can check the details on &lt;a href="https://caniuse.com/css-rrggbbaa" rel="noopener noreferrer"&gt;caniuse.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  RGB
&lt;/h2&gt;

&lt;p&gt;Color space: &lt;strong&gt;sRGB&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;RGB notation is similar to hexadecimal notation, with the main difference being that the channel values are easier to read. For example, understanding what #39 means is a bit more complicated than R 147. RGB notation is not used as often as hexadecimal notation, but it can be useful in certain situations, such as when creating a linear gradient or working with more complex color schemes. In general, the specific color values used by designers and developers are less important than the final product, which is why hexadecimal notation is more commonly used.&lt;/p&gt;

&lt;h2&gt;
  
  
  HSL
&lt;/h2&gt;

&lt;p&gt;Color space: &lt;strong&gt;sRGB&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Although the HSL color model uses the sRGB color space, it has fewer available colors than RGB or hexadecimal notation. This is because 360 x 100 x 100 equals 3.6 million, which is much smaller than the 16.8 million colors available in the RGB model. This limitation can be overcome by using decimal points in your HSL definitions, but this is not a widely used practice.&lt;/p&gt;

&lt;p&gt;One major advantage of HSL is that it is much easier to read and understand than hexadecimal or RGB notation. This is why it is the most commonly used color model for selecting colors for the web. However, we have written a &lt;a href="https://atmos.style/blog/lch-color-space?utm_campaign=web-colors&amp;amp;utm_source=blog&amp;amp;utm_medium=dev" rel="noopener noreferrer"&gt;blog post&lt;/a&gt; explaining why LCH color space is a better option for color selection.&lt;/p&gt;

&lt;p&gt;Overall, the HSL color space is a great choice for color wheels and color science because of its user-friendliness. If you want to try it out, check out our &lt;a href="https://atmos.style/color-wheel?utm_campaign=web-colors&amp;amp;utm_source=blog&amp;amp;utm_medium=dev" rel="noopener noreferrer"&gt;color wheel tool&lt;/a&gt; We think you'll like it!&lt;/p&gt;

&lt;h2&gt;
  
  
  HWB
&lt;/h2&gt;

&lt;p&gt;Color space: &lt;strong&gt;sRGB&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;HWB is similar to HSL, in that it is more user-friendly than RGB. However, we have not seen HWB used on the web. This makes sense because when selecting colors in RGB, HSL is often used as an intermediary step before converting the colors to hexadecimal notation. Therefore, there may not be a need for HWB in the typical web development workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  LCH &amp;amp; LAB
&lt;/h2&gt;

&lt;p&gt;Color space: &lt;strong&gt;CIE Lab&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CIE Lab is one of the largest color spaces in this list, it is even a bit larger than Display P3. It was designed to model human color perception, which means that the lightness values are consistent across all hues. This makes the color space more predictable and consistent than other alternatives. If you are interested in learning more about CIE Lab, we have written a &lt;a href="https://atmos.style/blog/lch-color-space?utm_campaign=web-colors&amp;amp;utm_source=blog&amp;amp;utm_medium=dev" rel="noopener noreferrer"&gt;detailed article about it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When it comes to color models, there are two options: LAB and LCH. On the web, LCH is a better choice because it is more intuitive and easier to use while LAB is better suited for scientific purposes.&lt;/p&gt;

&lt;p&gt;If you were to ask us which color format is the best, &lt;a href="https://atmos.style/blog/lch-color-space?utm_campaign=web-colors&amp;amp;utm_source=blog&amp;amp;utm_medium=dev" rel="noopener noreferrer"&gt;we would recommend LCH&lt;/a&gt;. Unfortunately, &lt;a href="https://caniuse.com/css-lch-lab" rel="noopener noreferrer"&gt;not all recent browsers support LCH&lt;/a&gt;, so it cannot be used as is. However, you can use this color space to create better color palettes. At &lt;a href="http://atmos.style/?utm_campaign=web-colors&amp;amp;utm_source=blog&amp;amp;utm_medium=dev" rel="noopener noreferrer"&gt;Atmos&lt;/a&gt;, we have designed a tool that allows anyone to take advantage of LCH on the web. Check it out!&lt;/p&gt;

&lt;h2&gt;
  
  
  Display P3
&lt;/h2&gt;

&lt;p&gt;Color space: &lt;strong&gt;Display P3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Color model and color space in and of itself. Display P3 is a color space developed by Apple to expand the range of colors available on computer screens. It covers 26% more of the visible light spectrum than sRGB, bringing a wider range of colors to the display. Display P3 was first implemented in the Safari web browser and, at the time of writing, is still the only browser that supports it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rec.2020
&lt;/h2&gt;

&lt;p&gt;Color space: &lt;strong&gt;Rec.2020&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rec.2020, also known as BT.2020, is not currently supported on the web. However, it is mentioned a few times in the &lt;a href="https://www.w3.org/TR/css-color-4/" rel="noopener noreferrer"&gt;CSS Color Module Level 4&lt;/a&gt;, so it is possible that it will be supported in the future. This color space is larger than Display P3, covering 75% of the visible light spectrum. Whether it will eventually get supported or not, it would be great if developers had a way to use wide color gamuts on the web, and the inclusion of rec.2020 in CSS Color Module Level 4 is a step in that direction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other wide gamut color spaces
&lt;/h2&gt;

&lt;p&gt;Adobe RGB, ProPhoto, Rec.2020, Rec.709, and other color spaces are supported on the web in some form, but not directly in CSS properties. There is a &lt;a href="https://webkit.org/blog-files/color-gamut/" rel="noopener noreferrer"&gt;detailed article&lt;/a&gt; about using wide-gamut images on the web that you may find interesting. Other color spaces may be visible in videos on YouTube or Netflix, but this does not count as direct support on the web. Despite this, it is interesting to know that these color spaces are being used in other contexts.&lt;/p&gt;

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

&lt;p&gt;Although LCH is the best color format for the web, it is not yet supported by all browsers. Therefore, we need continue to use the sRGB color space, either with the 6-character hexadecimal format for solid colors or the 8-character format for transparent colors. Until LCH support becomes more widespread, sRGB will remain the most commonly used color space on the web.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>api</category>
      <category>discuss</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Theming made easy with React and Styled Components</title>
      <dc:creator>Vojtěch Vidra</dc:creator>
      <pubDate>Wed, 16 Feb 2022 06:35:08 +0000</pubDate>
      <link>https://dev.to/vojtechvidra/theming-made-easy-with-react-and-styled-components-4ll9</link>
      <guid>https://dev.to/vojtechvidra/theming-made-easy-with-react-and-styled-components-4ll9</guid>
      <description>&lt;p&gt;Working with colors and creating a theme tends to get messy because colors are spread everywhere. We'll learn how to avoid common issues and organize colors better. In this article, you will learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to create a theme with Styled Components&lt;/li&gt;
&lt;li&gt;How to create Dark mode for a web app&lt;/li&gt;
&lt;li&gt;How to never duplicate colors in code&lt;/li&gt;
&lt;li&gt;How to take advantage of TypeScript to improve DX&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We've used this approach to create Dark mode for our app &lt;a href="https://atmos.style/?utm_source=blog&amp;amp;utm_medium=dev&amp;amp;utm_campaign=colors_code" rel="noopener noreferrer"&gt;Atmos&lt;/a&gt;. We can iterate on our color palette and change it in seconds, by sticking to these practices. Furthermore, anyone can jump into the code, thanks to the aligned naming convention of colors in design and code.&lt;/p&gt;

&lt;p&gt;Without further ado, let's jump right in!&lt;/p&gt;

&lt;h2&gt;
  
  
  Using variables
&lt;/h2&gt;

&lt;p&gt;Don't use colors directly. Always put them in a variable. CSS variables are better than SASS or JS variables, even if we're building a JS app with &lt;a href="https://styled-components.com/" rel="noopener noreferrer"&gt;styled-components&lt;/a&gt;. We will show you later in the article why.&lt;/p&gt;

&lt;p&gt;With this approach, we don't have to repeat ourselves. If we need to change one or more of our colors, it's just much easier to change the value of a variable instead of going through all those files and replacing them one by one.&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;.button&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="m"&gt;#123456&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;/* ⛔️ Not good, prefer variables */&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;--button-background&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c"&gt;/* ✅ Much better, don't repeat yourself */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using meaning
&lt;/h2&gt;

&lt;p&gt;It's pretty common to use the same color for a couple of elements. Maybe the color of our primary text is the same as the background color of our primary button. Now imagine the text is too light and doesn't have enough contrast. We will need to change the color of the text while keeping the original color for our button. That is why it's better to name our variables by their use case rather than their relation to the palette. For example, it is better to name a color &lt;code&gt;background&lt;/code&gt; rather than &lt;code&gt;white&lt;/code&gt;, or &lt;code&gt;button-background&lt;/code&gt; rather than &lt;code&gt;primary-dark&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This approach is great when building a dark mode that requires two separate palettes (one for light and one for dark). At that point, naming colors by their use case is the only sensible option.&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;.button&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;--primary-dark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c"&gt;/* ⛔️ Not good, in dark mode, it's probably not dark anymore. */&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;--button-background&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c"&gt;/* ✅ Much better, consistent with dark mode */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Naming convention
&lt;/h2&gt;

&lt;p&gt;A naming convention is a must-have for larger teams, but it makes sense even for smaller teams. It's like building Rest API without any documentation. In the example below, we can see inspect in Figma with the same color key [in square brackets] that we'll use in the React component next to it. Having the colors clearly named in Figma removes any questions about which colors to use, especially for new joiners.&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%2Fsuua5o3elb45iblr2r3z.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%2Fsuua5o3elb45iblr2r3z.png" alt="Inspect in Figma with description of color from React component" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sticking to one color notation
&lt;/h2&gt;

&lt;p&gt;When creating your theme, it's better to stick to one notation to avoid duplicate colors. There are a lot of options. Most of the time, colors are in hexadecimal format or RBGA when we need an alpha channel.&lt;/p&gt;

&lt;p&gt;It's better to use hexadecimal numbers because it's more concise. It can also be written in 8 character format to add an alpha channel &lt;a href="https://caniuse.com/css-rrggbbaa" rel="noopener noreferrer"&gt;with great browser support&lt;/a&gt;. In our codebase, we leverage the fact that we can append the last two characters of the alpha channel to a 6 character HEX code and share the same HEX code for non-transparent and transparent colors.&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;.button&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;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c"&gt;/* ℹ️ Alpha channel in % format is nicer. */&lt;/span&gt;

  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#12345678&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;/* ℹ️ This is shorter and more flexible. */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the future, we could also use a wide gamut &lt;a href="https://caniuse.com/css-color-function" rel="noopener noreferrer"&gt;display-p3&lt;/a&gt; or &lt;a href="https://caniuse.com/css-lch-lab" rel="noopener noreferrer"&gt;Lab&lt;/a&gt; color spaces. These can describe much more colors than RGB color space. Unfortunately, wide gamut colors are currently supported only in the latest Safari browser (early 2022).&lt;/p&gt;

&lt;h3&gt;
  
  
  Tip for converting percentages to HEX
&lt;/h3&gt;

&lt;p&gt;We may need to convert percentages to hexadecimal notation. The following is a simple JS function that will make our life easier.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;percentToHex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;percent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;percent&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Example:&lt;/span&gt;
&lt;span class="nf"&gt;percentToHex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: "FF"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Let's take a look at how to create a theme for your application. Using this method, we created a dark mode for &lt;a href="https://atmos.style/?utm_source=blog&amp;amp;utm_medium=dev&amp;amp;utm_campaign=colors_code" rel="noopener noreferrer"&gt;Atmos&lt;/a&gt; with ease. At the same time, we can iterate on our palette with little to no effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a theme
&lt;/h2&gt;

&lt;p&gt;First off, we will need a color palette. We can use a ready-made palette like Material UI or leverage our guide on &lt;a href="https://medium.com/atmos-style/how-to-create-the-best-ui-color-palette-abdd9f60c827" rel="noopener noreferrer"&gt;How to create the best UI color palette&lt;/a&gt; to create our own. We can also jump right into &lt;a href="https://atmos.style/?utm_source=blog&amp;amp;utm_medium=dev&amp;amp;utm_campaign=colors_code" rel="noopener noreferrer"&gt;Atmos&lt;/a&gt; to generate one in a matter of minutes.&lt;/p&gt;

&lt;p&gt;It could be tempting to take the color palette, turn it into a JS object, and call it a day. That would work (kinda), but there's a better way!&lt;/p&gt;

&lt;p&gt;In the code snippet below, we have two objects, our color palette, and our theme. Notice each has its purpose.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lightPalette&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#A3A4FF&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#8884FF&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#6C5EFA&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#573CFA&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="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lightTheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lightPalette&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lightPalette&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;500&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;h2&gt;
  
  
  Palette
&lt;/h2&gt;

&lt;p&gt;The palette stores your colors. Typically, the palette has primary, neutral, success, and danger colors. It's important to note that the palette should be the only place where we store our colors. There could be some HEX codes in our SVG icons, but we can always overwrite those using colors from our theme. Other than that, you won't find a single HEX outside of the palette.&lt;/p&gt;

&lt;h2&gt;
  
  
  Theme
&lt;/h2&gt;

&lt;p&gt;The theme gives meaning to our palette. For example background, text, text subtle, primary text, card background, icon, etc. As a rule of thumb, the theme is the only place, where the palette is used. If you need another color for your new component, don't use the palette directly, instead create a new item in your theme, and you're good to go. By sticking to this approach, the setup is very flexible and scalable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avoid flicker with CSS variables
&lt;/h2&gt;

&lt;p&gt;We have created a theme now we would like to use it. If you're using any CSS-in-JS tool, the most straightforward way is to pass the theme object into a Theme provider. That would work, but it has one major flaw you should consider if you're generating HTML during a build or request on the server, with frameworks like Next.js and Gatsby.&lt;/p&gt;

&lt;p&gt;Consider this scenario: You build your app for production, and by default, it is in light mode. The user enters your app and has dark mode selected. Because you have baked your colors into the generated JS classes, all your classes have to regenerate into the dark mode. That results in a brief flicker of light mode before the app regenerates the classes.&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%2Flvw11oav76sbk6rbhdaq.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%2Flvw11oav76sbk6rbhdaq.gif" alt="Flickering street lamp" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CSS variables to the rescue. Since you can create CSS variables for both light and dark themes at the build phase. All you need to do is apply the correct theme when a user enters your app. Do this by reading the user's preferred theme and setting the corresponding class name to the &lt;code&gt;html&lt;/code&gt; element. Because the CSS variables are still the same, your generated classes don't have to be regenerated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turning the theme into CSS variables
&lt;/h2&gt;

&lt;p&gt;With our theme ready, we need to turn it into CSS variables. We will use a recursive function that turns each atomic value into a CSS variable with the name from its object keys. The string then can be assigned directly to &lt;code&gt;:root&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createCssVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prefix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;flatMap&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&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="nx"&gt;varName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;createCssVar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ColorsItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;varName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;varName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createCssVars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;themeColors&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;createCssVar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// We're using lightTheme object from previous example&lt;/span&gt;
&lt;span class="nf"&gt;createCssVars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lightTheme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// This will turn into:&lt;/span&gt;
&lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="s2"&gt;`
--primary-text: #573CFA;
--primary-background: #6C5EFA;
`&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&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="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GlobalStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createGlobalStyle&lt;/span&gt;&lt;span class="s2"&gt;`
  :root {
    /* We assign variables to root element */
    &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;createCssVars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lightTheme&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;
  }
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Tip for Dark mode
&lt;/h3&gt;

&lt;p&gt;When building both light and dark modes, we will also need a way to assign the correct theme to the user based on their preferences. An easier option is to stick to the system settings, then all we need is &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme" rel="noopener noreferrer"&gt;this simple media query&lt;/a&gt;, and that's it.&lt;/p&gt;

&lt;p&gt;But we may want to allow users to choose between light and dark modes within the app UI and save the preferences. We can achieve this by injecting a simple script right after &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;, reading the local storage, and setting the class name for light/dark mode on the HTML element. We could try to come up with something ourselves, or we can use &lt;a href="https://github.com/donavon/use-dark-mode" rel="noopener noreferrer"&gt;this React hook that will do it for us&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Our awesome dark theme is almost ready. There's one last thing to do our scrollbars are probably still white. Not in Firefox, because Firefox uses system settings. To fix our scrollbars and also make them dark, there is a &lt;a href="https://web.dev/color-scheme/" rel="noopener noreferrer"&gt;simple css property or meta html tag&lt;/a&gt; to tell the browser that the scrollbar should be dark.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using CSS variables
&lt;/h2&gt;

&lt;p&gt;We have created a palette, light, maybe even dark theme. Now it's time to use our CSS variables. We can use it directly by referencing its value with standard CSS syntax.&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;.link&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;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--primary-text&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;Or we can create a simple (type-safe) function to help us with this. A great benefit is that the function doesn't need the theme reference (unlike the Theme Provider approach). From the code snippet below, we can see that the function can be used anywhere.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// If you're using TypeScript, see tip below for ColorKey type&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;colorKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ColorKey&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="nx"&gt;cssVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;colorKey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`var(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cssVar&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StyledButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="s2"&gt;`
  background-color: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary.background&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;svgRender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MySvg&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary.icon&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="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Tip for TypeScript
&lt;/h3&gt;

&lt;p&gt;We can leverage TypeScript and create a type that will help us when referencing our colors. &lt;a href="https://stackoverflow.com/questions/65332597/typescript-is-there-a-recursive-keyof?answertab=votes#tab-top" rel="noopener noreferrer"&gt;RecursiveKeyOf is a custom type&lt;/a&gt; that will take an object, chain its keys recursively, and create a string type joined by &lt;code&gt;.&lt;/code&gt;. This may sound complicated, but we don't need to understand it to use it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lightPalette is reference of our theme from earlier&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ColorKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;RecursiveKeyOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;lightTheme&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ColorKey is now union of colors from our theme.&lt;/span&gt;
&lt;span class="c1"&gt;// ColorKey is now basically this:&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ColorKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary.text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary.background&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  In conclusion (TLDR)
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Use variables, preferably CSS variables&lt;/li&gt;
&lt;li&gt;Name colors by their usage rather than how they look&lt;/li&gt;
&lt;li&gt;Create and stick to a naming convention&lt;/li&gt;
&lt;li&gt;Stick to one color notation, HEX or RGB, it doesn't matter&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you've enjoyed this article, I'm sure you will find Atmos helpful. Whether you are just starting with a new color palette, or your current palette could use some tweaking, then you should &lt;a href="https://atmos.style/?utm_source=blog&amp;amp;utm_medium=dev&amp;amp;utm_campaign=colors_code" rel="noopener noreferrer"&gt;give Atmos a shot&lt;/a&gt;! Hey, it's free 🚀&lt;/p&gt;

</description>
      <category>react</category>
      <category>css</category>
      <category>tutorial</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
