<?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: Lauri Lännenmäki</title>
    <description>The latest articles on DEV Community by Lauri Lännenmäki (@laurilllll).</description>
    <link>https://dev.to/laurilllll</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%2F378290%2F11b59b59-9c72-401f-82fe-a64c33d52b25.jpg</url>
      <title>DEV Community: Lauri Lännenmäki</title>
      <link>https://dev.to/laurilllll</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/laurilllll"/>
    <language>en</language>
    <item>
      <title>How to create Dark Mode using only CSS</title>
      <dc:creator>Lauri Lännenmäki</dc:creator>
      <pubDate>Thu, 03 Mar 2022 22:32:55 +0000</pubDate>
      <link>https://dev.to/laurilllll/how-to-create-dark-mode-using-only-css-2cb4</link>
      <guid>https://dev.to/laurilllll/how-to-create-dark-mode-using-only-css-2cb4</guid>
      <description>&lt;p&gt;Dark Mode and dark interfaces are not a new thing as they have been a trend for many years. When Apple released a dark mode option with the iOS 13 update back in 2019, the trend took off.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using modern CSS, you can create dark mode with a few lines of code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's dive in!&lt;/p&gt;

&lt;h4&gt;
  
  
  📚 Content
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Dark mode is more than a trend&lt;/li&gt;
&lt;li&gt;Dark mode is accessibility&lt;/li&gt;
&lt;li&gt;
How to set up dark mode with CSS

&lt;ul&gt;
&lt;li&gt;Create CSS Custom Properties (variables)&lt;/li&gt;
&lt;li&gt;Create conditional styling&lt;/li&gt;
&lt;li&gt;Apply styles&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Demo and final code&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  ✨ Bonus Content
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Color-scheme meta tag and CSS property&lt;/li&gt;
&lt;li&gt;
How to test your code

&lt;ul&gt;
&lt;li&gt;Google Chrome Dev Tools&lt;/li&gt;
&lt;li&gt;Device OS Settings&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  TL;DR;
&lt;/h2&gt;

&lt;p&gt;You can create dark mode using only &lt;strong&gt;CSS Custom Properties aka CSS variables&lt;/strong&gt; and &lt;strong&gt;CSS media feature &lt;code&gt;prefers-color-scheme&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

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

&lt;span class="c"&gt;/* 1. Create global variables for text and background color */&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;--color-text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* 2. Add conditional styling for dark mode preference */&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="c"&gt;/* Re-assign previous variables */&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;--color-text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* black =&amp;gt; white */&lt;/span&gt;
    &lt;span class="py"&gt;--color-background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* white =&amp;gt; black */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* 3. Assign variables to page color and background */&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;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;--color-text&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;--color-background&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;That's it 🔥 View my &lt;strong&gt;CSS Only Dark Mode&lt;/strong&gt; &lt;a href="https://codepen.io/laurilllll/pen/yLPKojZ" rel="noopener noreferrer"&gt;Codepen&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Dark mode is more than a trend
&lt;/h2&gt;

&lt;p&gt;Dark mode is not a design trend. Dark interfaces can be easier on the eyes and reduce eye strain and fatigue. They can actually help reduce the sensation of discomfort felt when staring at websites with light backgrounds.&lt;/p&gt;

&lt;p&gt;Dark mode also saves your device's battery life. It can reduce battery usage, especially on mobile devices.&lt;/p&gt;




&lt;h2&gt;
  
  
  Dark mode is accessibility
&lt;/h2&gt;

&lt;p&gt;Dark mode is also an accessibility (a11y) feature. &lt;strong&gt;It's about respecting your users and their preferences so they can use your website the way they like.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Besides responsive media queries, modern CSS has many cool media features and &lt;code&gt;prefers-color-scheme&lt;/code&gt; is one of them.  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme" rel="noopener noreferrer"&gt;Quote from MDN Web Docs&lt;/a&gt; 👇&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The prefers-color-scheme CSS media feature is used to detect if the user has requested a light or dark color theme. The user might indicate this preference through an operating system setting (e.g. light or dark mode) or a user agent setting.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Users can choose if they prefer light or dark mode from their operating system settings.&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%2Fs4llkxl3oc2oi1ju3mx4.png" 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%2Fs4llkxl3oc2oi1ju3mx4.png" alt="Picture from macOS general settings."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(macOS)&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%2Fzf9qaupb806yxk67fobl.png" 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%2Fzf9qaupb806yxk67fobl.png" alt="Picture from iOS Display &amp;amp; Brightness settings."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(iOS)&lt;/p&gt;

&lt;p&gt;With CSS, you can serve the user the theme they prefer. Media queries are used to conditionally apply styles. Media feature &lt;code&gt;prefers-color-scheme&lt;/code&gt; is a &lt;strong&gt;Media Query&lt;/strong&gt;, so you write it like you'd write your breakpoints:&lt;/p&gt;

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

&lt;span class="c"&gt;/* Breakpoint */&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;800px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* Add conditional styles here */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Prefers Color Scheme */&lt;/span&gt;
&lt;span class="c"&gt;/* Dark */&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="c"&gt;/* Add conditional styles here */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;/* Light */&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;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* Add conditional styles here */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;




&lt;h2&gt;
  
  
  How to set up dark mode with CSS
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Create CSS Custom Properties (variables)
&lt;/h4&gt;

&lt;p&gt;To setup color styles, I recommend using &lt;strong&gt;variables&lt;/strong&gt; to keep your code DRY (don't repeat yourself). If you aren't familiar with CSS variables, you can read about them from &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/--*" rel="noopener noreferrer"&gt;MDN Web Docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the sake of this tutorial we keep things simple and use black and white as our colors. And we only style our text color and background color.&lt;/p&gt;

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

&lt;span class="c"&gt;/* 1. Create global variables for text and background color */&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;--color-text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&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;h4&gt;
  
  
  Create conditional styling
&lt;/h4&gt;

&lt;p&gt;Next, let's apply &lt;strong&gt;conditional styling for users who prefer dark mode&lt;/strong&gt;. By using a media query, we re-assign previous variables with new inverted values.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="c"&gt;/* 2. Add conditional styling for dark mode preference */&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="c"&gt;/* Re-assign previous variables */&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;--color-text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* black =&amp;gt; white */&lt;/span&gt;
    &lt;span class="py"&gt;--color-background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* white =&amp;gt; black */&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;h4&gt;
  
  
  Apply styles
&lt;/h4&gt;

&lt;p&gt;And finally, we &lt;strong&gt;apply the variables&lt;/strong&gt; to our design:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="c"&gt;/* 3. Assign variables to page color and background */&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;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;--color-text&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;--color-background&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;
  
  
  Demo and final code
&lt;/h2&gt;

&lt;p&gt;See the final effect in action of user changing between light and dark mode in OS settings: &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%2Fzd6aqe9w1bidmjnu44ui.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%2Fzd6aqe9w1bidmjnu44ui.gif" alt="GIF animation of user changing between light and dark mode in OS settings."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👇 The final code in full.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="c"&gt;/* 1. Create global variables for text and background color */&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;--color-text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* 2. Add conditional styling for dark mode preference */&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="c"&gt;/* Re-assign previous variables */&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;--color-text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* black =&amp;gt; white */&lt;/span&gt;
    &lt;span class="py"&gt;--color-background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* white =&amp;gt; black */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* 3. Assign variables to page color and background */&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;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;--color-text&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;--color-background&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;You can view the code and play with it in my &lt;a href="https://codepen.io/laurilllll/pen/yLPKojZ" rel="noopener noreferrer"&gt;Codepen&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ Bonus Content
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Color-scheme meta tag and CSS property
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;color-scheme&lt;/code&gt; meta tag and CSS property takes care of two important things for you. This next quote is from &lt;a href="https://web.dev/color-scheme/" rel="noopener noreferrer"&gt;Google Developers web.dev&lt;/a&gt; and I've taken the liberty to highlight some parts of it 👇&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;They both make your life as a developer easier by allowing you to &lt;strong&gt;opt your page in to theme-specific defaults of the user agent stylesheet&lt;/strong&gt;, such as, for example, form controls, scroll bars, as well as CSS system colors. At the same time, this feature &lt;strong&gt;prevents browsers from applying any transformations on their own.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By the order of values, you can determine the default appearance. Here's the syntax for both CSS and the corresponding HTML meta tag:&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;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="n"&gt;light&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 the CSS example, the page author prefers &lt;strong&gt;dark&lt;/strong&gt; theme.)&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;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"color-scheme"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"light dark"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;(In the HTML example, the page author prefers &lt;strong&gt;light&lt;/strong&gt; theme.)&lt;/p&gt;

&lt;p&gt;It is recommended to specify the &lt;code&gt;color-scheme&lt;/code&gt; via the meta tag, so the browser can adopt to the preferred scheme faster.&lt;/p&gt;




&lt;h3&gt;
  
  
  How to test your code
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Google Chrome Dev Tools&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can test your code with Google Chrome Dev Tools.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open up your Dev Tools Inspection panel by pressing &lt;code&gt;Command+Option+C&lt;/code&gt; (Mac) or &lt;code&gt;Control+Shift+C&lt;/code&gt; (Windows, Linux, Chrome OS).&lt;/li&gt;
&lt;li&gt;Click on the &lt;strong&gt;three dots&lt;/strong&gt; in the &lt;strong&gt;upper right corner&lt;/strong&gt; =&amp;gt; select &lt;strong&gt;More tools&lt;/strong&gt; =&amp;gt; click &lt;strong&gt;Rendering&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;From the Rendering tab you can find the emulation for &lt;code&gt;prefers-colors-scheme&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;See the screenshots below 👇&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%2Fxp5k9l4zqn2i3ujfqrc7.png" 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%2Fxp5k9l4zqn2i3ujfqrc7.png" alt="Image of Google Chrome Dev Tools' Rendering tab highlighting prefers-color-scheme emulation."&gt;&lt;/a&gt;&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%2Fhilrpchexfd3yantizcc.png" 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%2Fhilrpchexfd3yantizcc.png" alt="Image of Google Chrome Dev Tools' Rendering tab prefers-color-scheme emulation turned to emulate dark mode."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Device OS settings&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As shown before, you can change the appearance from you device settings. Screenshots are from macOS and iOS. You can find the same settings from Android and Windows devices.&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%2Fs4llkxl3oc2oi1ju3mx4.png" 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%2Fs4llkxl3oc2oi1ju3mx4.png" alt="Picture from macOS general settings."&gt;&lt;/a&gt;&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%2Fzf9qaupb806yxk67fobl.png" 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%2Fzf9qaupb806yxk67fobl.png" alt="Picture from iOS Display &amp;amp; Brightness settings."&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources and further reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;CSS Only Dark Mode &lt;a href="https://codepen.io/laurilllll/pen/yLPKojZ" rel="noopener noreferrer"&gt;Codepen&lt;/a&gt; by me&lt;/li&gt;
&lt;li&gt;Color-scheme meta tag and CSS property at &lt;a href="https://web.dev/color-scheme/" rel="noopener noreferrer"&gt;web.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CSS Media Feature &lt;code&gt;prefers-color-scheme&lt;/code&gt; at &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme" rel="noopener noreferrer"&gt;MDN Web Docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CSS Custom Properties aka CSS Variables at &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/--*" rel="noopener noreferrer"&gt;MDN Web Docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Thank you 🙏
&lt;/h2&gt;

&lt;p&gt;I hope you found this article helpful 🔥&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://twitter.com/laurilllll" rel="noopener noreferrer"&gt;follow me on Twitter&lt;/a&gt; for more &lt;strong&gt;CSS&lt;/strong&gt;, &lt;strong&gt;Design System&lt;/strong&gt; and &lt;strong&gt;Figma&lt;/strong&gt; content 💪 &lt;/p&gt;

</description>
      <category>css</category>
      <category>design</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Figma Plugin API: How to Load and Use Fonts</title>
      <dc:creator>Lauri Lännenmäki</dc:creator>
      <pubDate>Sun, 06 Feb 2022 07:45:12 +0000</pubDate>
      <link>https://dev.to/laurilllll/figma-plugin-api-how-to-load-and-use-fonts-bj2</link>
      <guid>https://dev.to/laurilllll/figma-plugin-api-how-to-load-and-use-fonts-bj2</guid>
      <description>&lt;p&gt;Working with Figma text through the Figma Plugin API is a lot trickier than you might think. All the text inside Figma files are &lt;em&gt;nodes&lt;/em&gt; called &lt;strong&gt;TextNodes&lt;/strong&gt;. Essentially, nodes are &lt;strong&gt;layers&lt;/strong&gt; in Figma. With text nodes you have to think about &lt;em&gt;mixed styles&lt;/em&gt;, &lt;em&gt;missing fonts&lt;/em&gt; and &lt;em&gt;loading fonts&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For now, we concentrate on loading fonts.&lt;/p&gt;

&lt;p&gt;If you wish to change the content of a TextNode, &lt;strong&gt;you must load its font&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Here's one way of loading a font and manipulating text:&lt;/p&gt;

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

&lt;span class="c1"&gt;// Load font via async function&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myFontLoadingFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;await&lt;/span&gt; &lt;span class="nx"&gt;figma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadFontAsync&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Work Sans&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bold&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="c1"&gt;// Another function where we use the loaded font&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myAnotherFunction&lt;/span&gt; &lt;span class="o"&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="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Create text layer&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myTextLayer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;figma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="c1"&gt;// Set the font&lt;/span&gt;
  &lt;span class="nx"&gt;myTextLayer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fontName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Work Sans&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// Set text to uppercase&lt;/span&gt;
  &lt;span class="nx"&gt;myTextLayer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textCase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UPPER&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="c1"&gt;// Set text content&lt;/span&gt;
  &lt;span class="nx"&gt;myTextLayer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;characters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This is my title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="c1"&gt;// Add text layer to current page in Figma&lt;/span&gt;
  &lt;span class="nx"&gt;figma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myTextLayer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Use font only after the Promise is resolved&lt;/span&gt;
&lt;span class="nf"&gt;myFontLoadingFunction&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&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="nf"&gt;myAnotherFunction&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;That's basically it. If you want to know more about this subject, just keep on reading.&lt;/p&gt;




&lt;h3&gt;
  
  
  Glossary
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;About loading fonts&lt;/li&gt;
&lt;li&gt;How to load fonts&lt;/li&gt;
&lt;li&gt;What can you do with fonts and text&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can find the official &lt;em&gt;Figma Plugin documentation&lt;/em&gt; &lt;a href="https://www.figma.com/plugin-docs/api/TextNode/" rel="noopener noreferrer"&gt;page about &lt;strong&gt;TextNodes&lt;/strong&gt; here&lt;/a&gt; but I believe the docs could be better and that's why I wrote this blog post.&lt;/p&gt;




&lt;h2&gt;
  
  
  About loading fonts
&lt;/h2&gt;

&lt;p&gt;The docs tells us this important thing about text and fonts:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The important thing with text is that &lt;strong&gt;changing the content of a text node requires its font to be loaded and that fonts are not always available.&lt;/strong&gt; If you attempt to change, say, &lt;code&gt;fontName&lt;/code&gt; without first loading the font for that text node, the plugin will throw an exception.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I found out that the exception will look like this in your console.&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%2F68j548abd5v9xp9cyvqb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68j548abd5v9xp9cyvqb.jpg" alt="Image of an error in console."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, basically every time you make changes to text content or its properties, you have to load its font.&lt;/strong&gt; Only when you're changing properties like fill colour or stroke, you &lt;strong&gt;do not&lt;/strong&gt; need to load the fonts.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to load fonts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TextNodes&lt;/strong&gt; have a property called &lt;code&gt;fontName&lt;/code&gt; which is a javascript object that contains the font family and font style. The default font is &lt;code&gt;{ family: "Roboto", style: "Regular" }&lt;/code&gt;. In our example we want to use &lt;strong&gt;Work Sans, Bold&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;(As a sidenote: You can load any font thats already accessible in the Figma editor. You cannot load fonts from the internet.)&lt;/p&gt;

&lt;p&gt;The documentation says that &lt;em&gt;"Loading a font is done via &lt;code&gt;figma.loadFontAsync(fontname)&lt;/code&gt;"&lt;/em&gt; and maybe for someone that is enough but, as a designer, I was a bit confused when I tried it and it didn't work.&lt;/p&gt;

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

&lt;span class="c1"&gt;// Like in the docs =&amp;gt; figma.loadFontAsync(fontname)&lt;/span&gt;
&lt;span class="nx"&gt;figma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadFontAsync&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Work Sans&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bold&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;p&gt;On it's own, this code isn't enough. This is when the &lt;strong&gt;error&lt;/strong&gt; appears in the console. As we dive deeper into the docs we find this about the &lt;strong&gt;loadFontAsync&lt;/strong&gt; property:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(loadFontAsync) Makes a font available in the plugin for use when creating and modifying text. Calling this function is necessary to modify any property of a text node that may cause the rendered text to change, including .characters, .fontSize, .fontName, etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And from it's signature (found in the docs) &lt;code&gt;loadFontAsync(fontName: FontName): Promise&amp;lt;void&amp;gt;&lt;/code&gt; we can see that it returns a &lt;strong&gt;Promise&lt;/strong&gt;. So, we must enchance our code by creating an "async/await" function:&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myFontLoadingFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;await&lt;/span&gt; &lt;span class="nx"&gt;figma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadFontAsync&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Work Sans&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;After the &lt;strong&gt;loadFontAsync&lt;/strong&gt; Promise is resolved, we can use the &lt;code&gt;then()&lt;/code&gt; method that returns a new Promise and when that is a success we can do what we initially wanted.&lt;/p&gt;

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

&lt;span class="nf"&gt;myFontLoadingFunction&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&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="c1"&gt;// Success!&lt;/span&gt;

  &lt;span class="c1"&gt;// Add your code here to do something with the loaded font!&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;You can read more about &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise" rel="noopener noreferrer"&gt;Promises&lt;/a&gt; and the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then" rel="noopener noreferrer"&gt;&lt;code&gt;then()&lt;/code&gt;&lt;/a&gt; from the MDN docs.&lt;/p&gt;

&lt;p&gt;All the code once more:&lt;/p&gt;

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

&lt;span class="c1"&gt;// Load font via async function&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myFontLoadingFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;await&lt;/span&gt; &lt;span class="nx"&gt;figma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadFontAsync&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Work Sans&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bold&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="c1"&gt;// Another function where we use the loaded font&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myAnotherFunction&lt;/span&gt; &lt;span class="o"&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="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Create text layer&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myTextLayer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;figma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="c1"&gt;// Set the font&lt;/span&gt;
  &lt;span class="nx"&gt;myTextLayer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fontName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Work Sans&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// Set text to uppercase&lt;/span&gt;
  &lt;span class="nx"&gt;myTextLayer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textCase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UPPER&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="c1"&gt;// Set text content&lt;/span&gt;
  &lt;span class="nx"&gt;myTextLayer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;characters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This is my title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="c1"&gt;// Add text layer to current page in Figma&lt;/span&gt;
  &lt;span class="nx"&gt;figma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myTextLayer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Use font only after the Promise is resolved&lt;/span&gt;
&lt;span class="nf"&gt;myFontLoadingFunction&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&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="nf"&gt;myAnotherFunction&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;
  
  
  What can you do with fonts and text
&lt;/h2&gt;

&lt;p&gt;After you have your fonts loaded you can use the following properties and functions of a TextNode:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;characters&lt;/strong&gt; = set/write your text content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fontSize&lt;/strong&gt; = set font size&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fontName&lt;/strong&gt; = set font family and style/weight&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;textStyleId&lt;/strong&gt; = set TextStyle using TextStyle id&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;textCase&lt;/strong&gt; = set text casing to uppercase etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;textDecoration&lt;/strong&gt; = set decoration to underline/strikethrough&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;letterSpacing&lt;/strong&gt; = set letter spacing in pixels or percents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;lineHeight&lt;/strong&gt; = set line height in pixels or percents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;setRangeFontSize()&lt;/strong&gt; = set font size to characters in range&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;setRangeFontName()&lt;/strong&gt; = set font to characters in range&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;setRangeTextCase()&lt;/strong&gt; = set text casing to characters in range&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;setRangeTextDecoration()&lt;/strong&gt; = set text decoration to characters in range&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;setRangeLetterSpacing()&lt;/strong&gt; = set letter spacing to characters in range&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;setRangeLineHeight()&lt;/strong&gt; = set line height to characters in range&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;setRangeTextStyleId()&lt;/strong&gt; = set TextStyle to characters in range&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can check out all the &lt;strong&gt;TextNode&lt;/strong&gt; properties and functions &lt;a href="https://www.figma.com/plugin-docs/api/TextNode/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Have fun developing Figma plugins 🔥 I hope you found this article helpful!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/laurilllll" rel="noopener noreferrer"&gt;Follow me on Twitter&lt;/a&gt; for more &lt;strong&gt;Figma&lt;/strong&gt;, &lt;strong&gt;CSS&lt;/strong&gt; and &lt;strong&gt;Design System&lt;/strong&gt; content 💪 &lt;/p&gt;

</description>
      <category>typescript</category>
      <category>html</category>
      <category>figma</category>
      <category>plugin</category>
    </item>
    <item>
      <title>How to create responsive typography using CSS — Three different methods explained</title>
      <dc:creator>Lauri Lännenmäki</dc:creator>
      <pubDate>Wed, 20 Jan 2021 20:52:14 +0000</pubDate>
      <link>https://dev.to/laurilllll/how-to-create-responsive-typography-using-css-three-different-methods-explained-50f8</link>
      <guid>https://dev.to/laurilllll/how-to-create-responsive-typography-using-css-three-different-methods-explained-50f8</guid>
      <description>&lt;p&gt;Good typography is one of the key elements of a website. Let's take a look at &lt;strong&gt;three different methods&lt;/strong&gt; on &lt;strong&gt;how to create responsive typography using CSS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The three methods are:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Responsive typography using &lt;strong&gt;only media queries&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Responsive typography using &lt;strong&gt;a CSS custom property as a multiplier&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Responsive typography using &lt;strong&gt;the CSS clamp() function&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Check out the final &lt;a href="https://codepen.io/laurilllll/pen/ZEWZvBg"&gt;Codepen with all the methods&lt;/a&gt;. Resize the viewport to see the effect.&lt;/p&gt;




&lt;h3&gt;
  
  
  Why should you use responsive typography?
&lt;/h3&gt;

&lt;p&gt;The web is used on various screen sizes. Your site has to work on &lt;strong&gt;mobile&lt;/strong&gt;, &lt;strong&gt;tablet&lt;/strong&gt;, &lt;strong&gt;laptop&lt;/strong&gt;, &lt;strong&gt;desktop&lt;/strong&gt; and basically everything in between so there's a lot to take into consideration.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All of the method examples below are &lt;strong&gt;simplified&lt;/strong&gt; as they only cover &lt;strong&gt;three selectors&lt;/strong&gt; and &lt;strong&gt;one breakpoint&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can use this simple &lt;strong&gt;HTML&lt;/strong&gt; to try out all the methods in this tutorial:&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;h1&amp;gt;&lt;/span&gt;How to create responsive typography using CSS&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
  Vestibulum molestie sapien eget orci pellentesque, et aliquam lectus convallis. Phasellus neque velit, ultricies ut lacus at, finibus lobortis dui. Proin eget diam elit.
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Three different methods explained&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
  Pellentesque sagittis nisl nec rhoncus porta. Quisque luctus turpis nec turpis consequat fermentum et vitae diam.
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Let's dig in!&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Method 1: Responsive typography using only media queries
&lt;/h2&gt;

&lt;p&gt;This is the most basic method in our list.&lt;/p&gt;

&lt;p&gt;Simply, &lt;strong&gt;declare your text styles&lt;/strong&gt; and &lt;strong&gt;increase the font-size on bigger screens&lt;/strong&gt; using a breakpoint:&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="c"&gt;/* Declare text styles */&lt;/span&gt;
&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Increase font sizes by 1.5x on bigger screens */&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;48rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.25em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5em&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;Check out the result from this &lt;a href="https://codepen.io/laurilllll/pen/bGwJbJb"&gt;Codepen&lt;/a&gt;. Resize the viewport to see the effect.&lt;/p&gt;

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

&lt;p&gt;Using this method is totally fine and it does the job very well.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;downside is the large amount of code&lt;/strong&gt; you have to write. The codebase gets larger with every new selector you need to add. You have to write the styles &lt;strong&gt;separately&lt;/strong&gt; for &lt;strong&gt;every selector in each breakpoint&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In a real world you would probably have text selectors &lt;strong&gt;h1&lt;/strong&gt;, &lt;strong&gt;h2&lt;/strong&gt;, &lt;strong&gt;h3&lt;/strong&gt;, &lt;strong&gt;h4&lt;/strong&gt;, &lt;strong&gt;h5&lt;/strong&gt;, &lt;strong&gt;h6&lt;/strong&gt;, &lt;strong&gt;p&lt;/strong&gt; and at least &lt;strong&gt;two breakpoints&lt;/strong&gt;. At that point, this code is would've already gone &lt;strong&gt;from 20 lines to 67 lines&lt;/strong&gt;. That's &lt;strong&gt;3.35x&lt;/strong&gt; increase in the amount of code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The next method will show how to &lt;strong&gt;decrease the code amount&lt;/strong&gt; and make it &lt;strong&gt;easier to maintain!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Method 2: Responsive typography using a CSS custom property as a multiplier
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CSS custom properties&lt;/strong&gt; (variables) are super powerful. In the previous method, we increased the font sizes &lt;em&gt;manually&lt;/em&gt; one selector at a time. Now, we'll &lt;strong&gt;declare a multiplier variable&lt;/strong&gt; for the font-sizes and only &lt;strong&gt;increase the value of the multiplier&lt;/strong&gt; inside a breakpoint.&lt;/p&gt;

&lt;p&gt;Let's look at the code example in full and then break it down:&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="c"&gt;/* Declare a font size multiplier variable */&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;--text-multiplier&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="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Increase the size of the multiplier on bigger screens */&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;48rem&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;--text-multiplier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5&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="c"&gt;/* Declare text styles using calc() function and the multiplier */&lt;/span&gt;
&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2em&lt;/span&gt; &lt;span class="err"&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;--text-multiplier&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.5em&lt;/span&gt; &lt;span class="err"&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;--text-multiplier&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1em&lt;/span&gt; &lt;span class="err"&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;--text-multiplier&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;Check out the result from this &lt;a href="https://codepen.io/laurilllll/pen/ZEpZzPB"&gt;Codepen&lt;/a&gt;. Resize the viewport to see the effect.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;The first step&lt;/strong&gt; is to &lt;strong&gt;declare a variable&lt;/strong&gt; that we use to control our font size later on. We set the default value to &lt;strong&gt;1&lt;/strong&gt;.&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;--text-multiplier&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The second step&lt;/strong&gt; is to &lt;strong&gt;increase the multiplier value&lt;/strong&gt; inside a breakpoint. Unlike SASS variables, CSS custom properties &lt;strong&gt;can be used inside media queries&lt;/strong&gt;.&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;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;48rem&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;--text-multiplier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5&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;&lt;strong&gt;The last step&lt;/strong&gt; is to declare our font-sizes but this time we use &lt;strong&gt;the calc() function&lt;/strong&gt; so we can utilise our &lt;strong&gt;multiplier&lt;/strong&gt;.&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;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2em&lt;/span&gt; &lt;span class="err"&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;--text-multiplier&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.5em&lt;/span&gt; &lt;span class="err"&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;--text-multiplier&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1em&lt;/span&gt; &lt;span class="err"&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;--text-multiplier&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, &lt;strong&gt;we only need to declare our font sizes once&lt;/strong&gt;. This is a huge improvement compared to the first method.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Compared to the first method, we only have &lt;strong&gt;17 lines of code compared to 20&lt;/strong&gt;. If we would add four more selectors and one breakpoint, our code would &lt;strong&gt;only increase from 17 lines to 34&lt;/strong&gt;. Remember that using the first method it would require &lt;strong&gt;67 lines&lt;/strong&gt;. Almost twice as much.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The decrease of code is due to our elegant way of using a &lt;strong&gt;CSS custom property as a multiplier&lt;/strong&gt;. Adding another breakpoint takes only &lt;strong&gt;three lines of code&lt;/strong&gt; because we don't have to modify our font sizes at all. The code is also a lot &lt;strong&gt;easier to maintain and modify&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Adding breakpoints is as simple as:&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="c"&gt;/* Add more breakpoints */&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;64rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--text-multiplier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.75&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;80rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--text-multiplier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.0&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;To the user, this methods &lt;strong&gt;looks exactly the same&lt;/strong&gt; as the first but &lt;strong&gt;the code is much better&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Next up, we'll take a look at a &lt;strong&gt;new CSS clamp() function&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Method 3: Responsive typography using the CSS clamp() function
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;clamp() function&lt;/strong&gt; is pretty powerful! You can set a value using three parameters: &lt;strong&gt;a minimum value&lt;/strong&gt;, &lt;strong&gt;a preferred value&lt;/strong&gt; and &lt;strong&gt;a maximum value&lt;/strong&gt;. Basically you'll have a 3-in-1 value!&lt;/p&gt;

&lt;p&gt;Example declaration for responsive text using the &lt;strong&gt;clamp() function&lt;/strong&gt; looks 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;font-size: clamp(2rem, 5vw, 3rem);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows us to create responsive typography &lt;strong&gt;without any media queries&lt;/strong&gt;. &lt;strong&gt;With only one line of code&lt;/strong&gt; we set the minimum value (mobile), the maximum value (desktop) and the preferred value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The font size will become fluid&lt;/strong&gt; as it will always be the &lt;strong&gt;preferred value inside the min-max range&lt;/strong&gt;. Very powerful!&lt;/p&gt;

&lt;p&gt;To set the responsive typography for our demo, it is as simple as 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="c"&gt;/* Declare text styles */&lt;/span&gt;
&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* Font minimum, preferred and maximum value */&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;clamp&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;--min&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;--val&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;--max&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Font size variables */&lt;/span&gt;
&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--min&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="c"&gt;/* minimum value */&lt;/span&gt;
  &lt;span class="py"&gt;--val&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* preferred value = 5% viewport width */&lt;/span&gt;
  &lt;span class="py"&gt;--max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* maximum value */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c"&gt;/* minimum value */&lt;/span&gt;
  &lt;span class="py"&gt;--val&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c"&gt;/* preferred value = 4% viewport width */&lt;/span&gt;
  &lt;span class="py"&gt;--max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.25em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c"&gt;/* maximum value */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c"&gt;/* minimum value */&lt;/span&gt;
  &lt;span class="py"&gt;--val&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.5vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* preferred value = 2.5% viewport width */&lt;/span&gt;
  &lt;span class="py"&gt;--max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* maximum value */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check out the result from this &lt;a href="https://codepen.io/laurilllll/pen/ExgJYRm"&gt;Codepen&lt;/a&gt;. Resize the viewport to see the effect.&lt;/p&gt;

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

&lt;p&gt;If you look at the code, you'll see that by using &lt;strong&gt;CSS custom properties together with the clamp() function&lt;/strong&gt; we are able to &lt;strong&gt;declare all the text styles at the same time with only on line of code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After that, we just set the &lt;strong&gt;--min&lt;/strong&gt;, &lt;strong&gt;--val&lt;/strong&gt; and &lt;strong&gt;--max&lt;/strong&gt; custom properties for each selector and we are done!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;CSS custom properties can be &lt;strong&gt;scoped inside selectors&lt;/strong&gt; so you can &lt;strong&gt;use the same custom properties with multiple selectors&lt;/strong&gt; just like we have done here with our &lt;strong&gt;h1&lt;/strong&gt;, &lt;strong&gt;h2&lt;/strong&gt; and &lt;strong&gt;p&lt;/strong&gt;. These custom properties will not clash together even though they have the same name.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This method takes up 18 lines of code and with four more selectors and one breakpoint it would be 38 lines. So, it's slightly larger than on the second method but we get &lt;strong&gt;fluid typography&lt;/strong&gt; in return.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &lt;strong&gt;clamp() function&lt;/strong&gt; is pretty new, so you should check if it has the browser support you need from &lt;a href="https://caniuse.com/css-math-functions"&gt;caniuse.com&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CSS is powerful!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In many cases, there's more than one way to achieve the desired result.&lt;/p&gt;

&lt;p&gt;If you read this far, thank you! I hope you learned something new.&lt;/p&gt;

&lt;p&gt;Here's the final &lt;a href="https://codepen.io/laurilllll/pen/ZEWZvBg"&gt;Codepen with all the methods&lt;/a&gt; once more. Resize the viewport to see the effect.&lt;/p&gt;

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




&lt;h2&gt;
  
  
  Thank you 🙏
&lt;/h2&gt;

&lt;p&gt;I hope you found this article helpful 🔥&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://twitter.com/laurilllll"&gt;follow me on Twitter&lt;/a&gt; for more &lt;strong&gt;CSS&lt;/strong&gt;, &lt;strong&gt;Design System&lt;/strong&gt; and &lt;strong&gt;Figma&lt;/strong&gt; content 💪 &lt;/p&gt;

</description>
      <category>css</category>
      <category>html</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
