<?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: Oscar</title>
    <description>The latest articles on DEV Community by Oscar (@owl).</description>
    <link>https://dev.to/owl</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%2F40446%2F19dcd4f3-7102-4aff-8d0f-398ea327c711.jpg</url>
      <title>DEV Community: Oscar</title>
      <link>https://dev.to/owl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/owl"/>
    <language>en</language>
    <item>
      <title>Die Nächte sind erfüllt von Maskenfesten</title>
      <dc:creator>Oscar</dc:creator>
      <pubDate>Wed, 05 Feb 2020 12:27:37 +0000</pubDate>
      <link>https://dev.to/owl/die-nachte-sind-erfullt-von-maskenfesten-1919</link>
      <guid>https://dev.to/owl/die-nachte-sind-erfullt-von-maskenfesten-1919</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: This post has originally &lt;a href="https://www.ovl.design/text/die-naechte-sind-erfuellt-von-maskenfesten"&gt;been published on my own blog&lt;/a&gt;. If you want to see the implementation in a live environment, have a look over there.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I’m late to the party. I can’t help it. If there is a possibility to be late, I am. But I do like a party. Sometimes I even do like parties in dark rooms. So, implementing dark mode has been out of question. &lt;/p&gt;

&lt;p&gt;I had implemented it on two sites I built from scratch recently. It was so straight-forward that I thought it couldn’t be too hard for this site. The only different thing is that the code for this site is a bit … it is code written by someone who did not know what they were doing. Read: a younger me. &lt;/p&gt;

&lt;p&gt;In the following I am showing you how I approached it, as well as explaining the basics of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/--*"&gt;CSS Custom Properties&lt;/a&gt;, as they are an integral part of the implementation. &lt;/p&gt;

&lt;h2&gt;
  
  
  Getting colourful
&lt;/h2&gt;

&lt;p&gt;Luckily,  I knew that it is a good idea to keep your colours somewhere safe and only use named variants in your CSS, just in case red does not cut it as the primary colour anymore and you want to switch to something different. &lt;/p&gt;

&lt;p&gt;Here are all colours I use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;colors&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;#b00000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nt"&gt;main-light&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;lighten&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;#b00000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;30&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
  &lt;span class="nt"&gt;main-dark&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;darken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;#b00000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;10&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
  &lt;span class="nt"&gt;light&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;#f8f2e3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nt"&gt;dark&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#0&lt;/span&gt;&lt;span class="nt"&gt;e0e0e&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nt"&gt;dark-lighter&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#685&lt;/span&gt;&lt;span class="nt"&gt;d5d&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nt"&gt;light-darker&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;#cdc9bd&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;

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



&lt;p&gt;Up until now, I’ve been using them through a SASS function named &lt;code&gt;color&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@function&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;@if&lt;/span&gt; &lt;span class="n"&gt;map-has-key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;@return&lt;/span&gt; &lt;span class="n"&gt;map-get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;@warn&lt;/span&gt; &lt;span class="s1"&gt;"Unknown `#{$key}` in $colors."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;@return&lt;/span&gt; &lt;span class="n"&gt;null&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;If I want to make something red (my main colour), I have used it as such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.main-headline&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;'main'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;fonts-secondary&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;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--type-xlarge&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;double&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="n"&gt;space&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;half&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="err"&gt;&amp;amp;:first-child&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This has been alright since the site never needed to change these values once they were parsed into my stylesheet. Now, with the ominous dark mode, I need to do this. If a media query matches, all the colours need to change.  &lt;/p&gt;

&lt;p&gt;Putting a media query everywhere I need a colour change is tedious. Work I would probably don’t do properly. Luckily, there’s another way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enter custom properties
&lt;/h3&gt;

&lt;p&gt;Custom properties, often called CSS variables, are a kind-of-new addition to a web designer’s toolbox. The name variables gives it away: They make value definitions &lt;em&gt;variable&lt;/em&gt;. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/--*#Browser_compatibility"&gt;Browser support&lt;/a&gt; is solid since a while, with every browser except IE 11 supporting them. If you care about providing a fallback for not supporting browser – &lt;a href="https://www.ovl.design/text/a-non-business-case-for-supporting-old-browsers"&gt;which you should&lt;/a&gt; – there is a &lt;a href="https://github.com/postcss/postcss-custom-properties"&gt;PostCSS plugin&lt;/a&gt; which adds a static fallback to your definitions.&lt;/p&gt;

&lt;p&gt;Before I talk about switching colours, let me give you a brief introduction to how these custom properties aka variables work. &lt;/p&gt;

&lt;p&gt;Let’s create a utility class for a square box.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.is-square&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&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;If you need a different size, you would need to create a modifier and redeclare all values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.is-square&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="err"&gt;&amp;amp;--large&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Things will get verbose quite quickly, as more complex code bases tend to need boxes in many different sizes. &lt;/p&gt;

&lt;p&gt;The cool thing about custom properties is that they allow you to overwrite them as needed, allowing for much more flexibility. Let’s refactor the box to use custom properties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.is-square&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--box-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;height&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;--box-size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;width&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;--box-size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;On line 2, we have declared the property, or variable, and used it for both &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; by calling the &lt;code&gt;var&lt;/code&gt; function. &lt;/p&gt;

&lt;p&gt;Tip: Always namespace such properties. Just naming it &lt;code&gt;--size&lt;/code&gt; invites a whole lot of trouble, since it’s very like that at one point another declaration will define &lt;code&gt;--size&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Defining other sizes becomes much easier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.is-square&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--box-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;height&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;--box-size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;width&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;--box-size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="err"&gt;&amp;amp;--large&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;--box-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As the value of &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; is variable, we can change both by redeclaring the variable.&lt;/p&gt;

&lt;p&gt;And if there is a use case where you need a slightly different box, you can do so from everywhere in your CSS.&lt;/p&gt;

&lt;p&gt;Say we have an avatar in a user profile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"user-avatar is-square"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt; &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Profile picture of Jane Doe"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After adding the &lt;code&gt;is-square&lt;/code&gt; utility class, we can redefine the size by updating the &lt;code&gt;--box-size&lt;/code&gt; property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.user-avatar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--box-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&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;The &lt;code&gt;--box-size&lt;/code&gt; variable is scoped into the class we first defined it in. There is a way to declare «global» variables. &lt;/p&gt;

&lt;p&gt;Coming back to colours, let’s take a look at an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;--clr-main&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#b00000&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;Once declared, we can use the property &lt;code&gt;--clr-main&lt;/code&gt; everywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.main-headline&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;--clr-main&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;One last thing that’s good to know about using custom properties is that you can specify a fallback value, by adding a second parameter to the function call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.main-headline&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;--clr-main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#b00000&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;Stefan Judis recently &lt;a href="https://twitter.com/stefanjudis/status/1222987075018010631"&gt;tweeted about a little trick&lt;/a&gt;, with which «you can use undefined properties with a fallback value to then define them later».&lt;/p&gt;

&lt;h3&gt;
  
  
  Making colours variable
&lt;/h3&gt;

&lt;p&gt;The first step is to declare all the colours. I could do this by hand, but as I’ve stored them in a SASS map already, a loop saves a bit of time here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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="err"&gt;@each&lt;/span&gt; &lt;span class="err"&gt;$color,&lt;/span&gt;
  &lt;span class="err"&gt;$value&lt;/span&gt; &lt;span class="err"&gt;in&lt;/span&gt; &lt;span class="err"&gt;$colors&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;--clr-#{$color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I use the &lt;code&gt;--clr&lt;/code&gt; namespace for colours, to avoid name-clashing and be clear what kind of value to expect. &lt;/p&gt;

&lt;p&gt;And while the map saves me typing, I also find it easier to scan and maintain, than a list of property definition, but that’s a personal preference.&lt;/p&gt;

&lt;p&gt;In the parsed CSS it will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;--clr-main&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#b00000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--clr-main-light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ff4a4a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--clr-main-dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#7d0000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--clr-light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f8f2e3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--clr-dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0e0e0e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--clr-dark-lighter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#685d5d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--clr-light-darker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#cdc9bd&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;h3&gt;
  
  
  Naming can be confusing
&lt;/h3&gt;

&lt;p&gt;One step I took before actually implementing dark mode, was to add a layer of naming. Why’s that? Because, in dark mode,  light becomes dark and I always find it confusing to see a declaration like &lt;code&gt;color: var(--clr-dark)&lt;/code&gt; and see light text in the browser. &lt;/p&gt;

&lt;p&gt;Aliasing the colours makes my design decisions more evident:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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="err"&gt;@each&lt;/span&gt; &lt;span class="err"&gt;$color,&lt;/span&gt;
  &lt;span class="err"&gt;$value&lt;/span&gt; &lt;span class="err"&gt;in&lt;/span&gt; &lt;span class="err"&gt;$colors&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;--clr-#{$color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="err"&gt;}&lt;/span&gt;

  &lt;span class="nt"&gt;--clr-bg&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--clr-light&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;--clr-fg&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--clr-dark&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;--clr-accent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--clr-main&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;--clr-accent-dark&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--clr-main-dark&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;--clr-accent-light&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--clr-main-light&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;--clr-decent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--clr-dark-lighter&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;These declarations make it very clear which &lt;em&gt;purpose&lt;/em&gt; the colour fulfils, and abstracts from the actual value, which is not as important anymore. &lt;/p&gt;

&lt;p&gt;Using these classes looks something like this, nice, clean and declarative.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--clr-bg&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;--clr-fg&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;The last thing left to do was to do a search and replace for all places where I’ve used the &lt;code&gt;color&lt;/code&gt; SASS function and replace these declarations with my new variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.main-headline&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;--clr-accent&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;h3&gt;
  
  
  Getting dark
&lt;/h3&gt;

&lt;p&gt;Now, finally to updating colours for dark mode. I target a dark mode user preference using the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme"&gt;prefers-color-scheme&lt;/a&gt; media feature. It’s supported by all browsers that also support custom properties. &lt;/p&gt;

&lt;p&gt;After setting up the project, the change is straight forward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;--clr-fg&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;--clr-light&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;--clr-bg&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;--clr-dark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;--clr-accent&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;--clr-main-light&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;--clr-accent-dark&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;--clr-main-light&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;--clr-accent-light&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;--clr-main-dark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;--clr-decent&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;--clr-light-dark&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;If the media query matches, I invert my color scheme, and since I use &lt;code&gt;var()&lt;/code&gt; everywhere, these changes will cascade down from the root element. &lt;/p&gt;

&lt;p&gt;The cascade is a beautiful feature. If you are starting out learning CSS and it feels a bit daunting, Amelia Wattenberger has recently published &lt;a href="https://wattenberger.com/blog/css-cascade"&gt;a fantastic primer on how it works&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Two names I’m not happy with are &lt;code&gt;accent-dark&lt;/code&gt; and &lt;code&gt;accent-light&lt;/code&gt;. Currently, I do what I didn’t want to do: applying a light colour to a dark name and vice versa. Naming &lt;em&gt;is&lt;/em&gt; hard. I tend to change this to &lt;code&gt;accent-to&lt;/code&gt; and &lt;code&gt;accent-from&lt;/code&gt; as I use them mostly for gradients. Let’s see what I come up with.&lt;/p&gt;

&lt;h3&gt;
  
  
  Colour is complicated
&lt;/h3&gt;

&lt;p&gt;Inverting the colour setting was a valuable first draft, but not the end of the story. My standard dark colour is very close to true black, which feels quite harsh when applied as a page background. I brightened my dark grey a bit to reduce this.&lt;/p&gt;

&lt;p&gt;The second value I tweaked was &lt;code&gt;--clr-accent&lt;/code&gt;. In the swap out version I used the light shade of the main colour. I did so to maintain the contrast between it and the background. But now my design was missing a colour, and the light shade felt very bright when used for large type. To mitigate this I used a slightly darker red as the accent colour.&lt;/p&gt;

&lt;p&gt;This is the colour scheme in use now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;--clr-fg&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;--clr-light&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;--clr-bg&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;--clr-dark-lighter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;--clr-accent&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;--clr-main-darker&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;--clr-accent-dark&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;--clr-main-light&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;--clr-accent-light&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;--clr-main-dark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;--clr-decent&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;--clr-light-dark&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;Even with a fairly simple colour scheme like mine, simply swapping out colours wasn’t a satisfactory solution. Things get even more complicated when the colour scheme gets more nuanced. &lt;/p&gt;

&lt;p&gt;In another project I ended up creating not one but two maps. Instead of looping over all colours once and assigning them afterwards, I looped over each separately.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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="err"&gt;@each&lt;/span&gt; &lt;span class="err"&gt;$color,&lt;/span&gt; &lt;span class="err"&gt;$value&lt;/span&gt; &lt;span class="err"&gt;in&lt;/span&gt; &lt;span class="err"&gt;$colors&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;--clr-#{$color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;@each&lt;/span&gt; &lt;span class="err"&gt;$color,&lt;/span&gt; &lt;span class="err"&gt;$value&lt;/span&gt; &lt;span class="err"&gt;in&lt;/span&gt; &lt;span class="err"&gt;$colors-dark&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
      &lt;span class="err"&gt;--clr-#{$color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As the keys in both maps are identical, usage didn’t change after the variables were declared.&lt;br&gt;
Regardless which approach you take, make sure to test for &lt;a href="https://www.w3.org/TR/WCAG20-TECHS/G18.html"&gt;contrast ratio&lt;/a&gt;, legibility and harmony. &lt;/p&gt;

&lt;p&gt;A quick note on handling type: White text on a black background tends to appear smaller than dark text on a light background. You might need to tweak your font sizes, especially the small ones.&lt;/p&gt;
&lt;h3&gt;
  
  
  For the heart
&lt;/h3&gt;

&lt;p&gt;With all colours updated there was one final, but essential, step to take. You might have noticed the small little floral heart underneath the title of this article. It called &lt;a href="https://en.wikipedia.org/wiki/Fleuron_(typography)"&gt;Fleuron&lt;/a&gt; and is a glyph with age-old origins. While it started as a punctuation mark, today it is mostly used as an ornamental mark as I do on my side. You may also find it as a divider on the &lt;a href="https://www.ovl.design/text"&gt;text archive page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I load the image as an SVG file and have the gradient lines on each side of it. This needs to adapt, too. &lt;/p&gt;

&lt;p&gt;The CSS for it is a bit more involved (and most likely deserves a clean up). Let’s take a look at what I had for a start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.u-floral-heart-gradient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nb"&gt;right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main-light&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main-dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="sx"&gt;url('~assets/img/icons/floral-heart-dark-red.svg')&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nb"&gt;right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main-dark&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main-light&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="nl"&gt;background-position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4vmin&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;100%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;center&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;100%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1.66rem&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;100%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;4vmin&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;100%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;background-repeat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40%&lt;/span&gt; &lt;span class="m"&gt;0.125rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;40%&lt;/span&gt; &lt;span class="m"&gt;0.125rem&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;Breaking it down, we have three &lt;code&gt;background-images&lt;/code&gt;s, which are a gradient, the fleuron, and another gradient. They are sized to always fit into the container and are positioned at the bottom of it. &lt;/p&gt;

&lt;p&gt;First, I replaced the colours with variable calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.u-floral-heart-gradient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nb"&gt;right&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;--clr-accent-light&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;--clr-accent-dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="sx"&gt;url('~assets/img/icons/floral-heart-dark-red.svg')&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nb"&gt;right&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;--clr-accent-dark&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;--clr-accent-light&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="nl"&gt;background-position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4vmin&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;100%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;center&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;100%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1.66rem&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;100%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;4vmin&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;100%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;background-repeat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40%&lt;/span&gt; &lt;span class="m"&gt;0.125rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;40%&lt;/span&gt; &lt;span class="m"&gt;0.125rem&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;The beautiful thing about custom properties is that you can assign any CSS property to them and make it work; this includes &lt;code&gt;url&lt;/code&gt; values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;--layout-fleuron&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('~assets/img/icons/floral-heart-dark-red.svg')&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;Swapping the SVG happens in the media query mentioned above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="c"&gt;/* colours omitted for brevity */&lt;/span&gt;

    &lt;span class="py"&gt;--layout-fleuron&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('~assets/img/icons/floral-heart-light-red.svg')&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;I now have an adapting fleuron that I can use by calling &lt;code&gt;var(--layout-heart)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For the gradient, I decided to take it one step further and replaced some more repeating values with custom properties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.u-floral-heart-gradient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--gradient-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40%&lt;/span&gt; &lt;span class="m"&gt;0.125rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--gradient-bottom-offset&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;100%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--fleuron-bottom-offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.66rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nb"&gt;right&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;--clr-accent-light&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;--clr-accent-dark&lt;/span&gt;&lt;span class="p"&gt;)&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;--layout-fleuron&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nb"&gt;right&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;--clr-accent-dark&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;--clr-accent-light&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="nl"&gt;background-position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4vmin&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;--gradient-bottom-offset&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;center&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;100%&lt;/span&gt; &lt;span class="n"&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;--fleuron-bottom-offset&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;100%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;4vmin&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;--gradient-bottom-offset&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;background-repeat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-size&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;--gradient-size&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="m"&gt;1rem&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;--gradient-size&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;I decided to make the bottom offset variable since this makes adapting it much more straightforward. Without these variables, I needed to update the whole &lt;code&gt;background-position&lt;/code&gt; declaration, even if just two numbers changed. &lt;/p&gt;

&lt;p&gt;The archive header uses my utility class but positions the fleuron and lines closer to the bottom. By modifying the offsets, the change is very clean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.archive-header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--gradient-bottom-offset&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;100%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--fleuron-bottom-offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.66rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;33vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&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;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;I wanted to implement dark mode and by doing so, ended up with a cleaner codebase and property names that communicate my design &lt;em&gt;intent&lt;/em&gt; rather than the blank values.&lt;/p&gt;

&lt;p&gt;Working with custom properties beyond colour updates opens a whole new world of piecing together CSS that I’m eager to explore. &lt;/p&gt;

&lt;p&gt;And, as always, good design requires nuance and a fair bit of staring at the screen. &lt;/p&gt;

&lt;p&gt;One thing I am going to add is a user toggle. If you are interested in this, Andy Bell has written an &lt;a href="https://hankchizljaw.com/wrote/create-a-user-controlled-dark-or-light-mode/"&gt;in-depth article about his approach&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowledgements
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://unsplash.com/photos/odWmII7vf6M"&gt;title image has been taken by Jimena Egger&lt;/a&gt; and published on Unsplash. &lt;/p&gt;

&lt;p&gt;The post is named after &lt;a href="https://www.youtube.com/watch?v=nuu9B4xAuPo"&gt;a song by the wonderful Bersarin Quartett&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>design</category>
    </item>
    <item>
      <title>A Non-Business Case for Supporting Old Browsers</title>
      <dc:creator>Oscar</dc:creator>
      <pubDate>Fri, 22 Nov 2019 14:14:30 +0000</pubDate>
      <link>https://dev.to/owl/a-non-business-case-for-supporting-old-browsers-2kgo</link>
      <guid>https://dev.to/owl/a-non-business-case-for-supporting-old-browsers-2kgo</guid>
      <description>&lt;p&gt;&lt;em&gt;This article has originally been published &lt;a href="https://www.ovl.design/text/a-non-business-case-for-supporting-old-browsers/"&gt;on my website&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;CSS Tricks has published yet another &lt;a href="https://css-tricks.com/a-business-case-for-dropping-internet-explorer/"&gt;take on why we all need to abandon support for IE 11&lt;/a&gt; as soon as possible.&lt;/p&gt;

&lt;p&gt;I think that’s wrong. Let me explain why.&lt;/p&gt;

&lt;p&gt;Often, when talking about «abandoning» support for a browser we forget that this simply isn’t possible. Users will visit your site with whatever browser they have at hand. Under whatever network conditions. And that’s okay. That’s great even. Resilience is one of the foundational principles of the Web.&lt;/p&gt;

&lt;p&gt;And it’s not just the Web. The internet itself around is build upon resilient layers. TCP/IP is dumb. And, &lt;a href="https://resilientwebdesign.com/chapter1/#The%20open%20architecture%20"&gt;as Jeremy Keith puts it&lt;/a&gt;, that is «its secret sauce».  Browsers were, from the beginning, instructed to ignore HTML (and later CSS) they do not understand; without breaking the whole document. &lt;/p&gt;

&lt;p&gt;In her article &lt;cite&gt;&lt;a href="https://css-tricks.com/teaching-css/"&gt;Teaching CSS&lt;/a&gt;&lt;/cite&gt; Rachel Andrew remarks &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Yet, a website built back then that is still online, or one accessed via the Wayback Machine will still work in a modern browser. Such is the care that has been taken to &lt;strong&gt;not break the web&lt;/strong&gt; by the CSS Working Group, and the other groups working to add features to the web platform.&lt;br&gt;
To call for abandonment runs afoul of this work and as such against the web itself. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In his talk &lt;cite&gt;&lt;a href="https://vimeo.com/373128517"&gt;The Layers of the Web&lt;/a&gt;&lt;/cite&gt; Jeremy Keith challenges this mindset by illustrating how languages on the web were build &lt;em&gt;upon another&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Websites aren’t just broken or working. At least they don’t have to be. This requires thinking in steps. And not to put everything in your JavaScript stack.&lt;/p&gt;

&lt;p&gt;The web, and I am going to lean on Jeremy Keith again, is not like other platforms. In fact, the word platform might not be apt to describe it at all. Maybe it’s more like a &lt;a href="https://adactio.com/journal/6692"&gt;continuum&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Which requires a different mindset, then one which just knows on or off. Building for the web offers the unique possibility of building experiences that are gradually enhanced.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Layers
&lt;/h2&gt;

&lt;p&gt;If we use HTML for Markup, CSS for styling and JS for behaviour sprinkled on top, we can go a long way towards supporting a multitude of User Agents.&lt;br&gt;
And while it certainly is true that including &lt;em&gt;all&lt;/em&gt; the polyfills will bloat the scripts to send, it is also true that this is a solved problem.&lt;/p&gt;

&lt;p&gt;Chris Coyier explained this in his article &lt;a href="https://css-tricks.com/differential-serving/"&gt;Differential Serving&lt;/a&gt;. We can use a clever combination of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules"&gt;JavaScript modules&lt;/a&gt; and the &lt;code&gt;nomodule&lt;/code&gt; attribute to load one version of our scripts to modern browsers, and the other to old ones that do not support &lt;code&gt;script type="module"&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Phil Walton has &lt;a href="https://philipwalton.com/articles/deploying-es2015-code-in-production-today/"&gt;described this approach in more depth&lt;/a&gt;. We are using this technique at Kitchen Stories in production since January. By using &lt;a href="https://v8.dev/features/dynamic-import"&gt;dynamic imports&lt;/a&gt; we can debundle our bundles even further.&lt;/p&gt;

&lt;p&gt;What goes for JS is also true for CSS. Even though the gains might be smaller here.&lt;/p&gt;

&lt;p&gt;All we need is a little bit of trickery with Media Queries. By adding the &lt;code&gt;media&lt;/code&gt; attribute to the &lt;code&gt;link&lt;/code&gt; tag that references a stylesheet it is only loaded if this Media Query evaluates to true.&lt;/p&gt;

&lt;p&gt;And here the layers strike again. If a browser does not understand a media query it will not load the styles, regardless if it encounters the query in a style block or a link. &lt;/p&gt;

&lt;p&gt;The tricky thing is knowing which queries to use. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;PSA&lt;/em&gt;: I am pretty sure I did not come up with the following solution by myself. But: I do not find the original source anymore. If you can point me somewhere please &lt;a href="https://twitter.com/_ovlb"&gt;ping me on Twitter&lt;/a&gt; and I will happily include a link in this article.&lt;/p&gt;

&lt;p&gt;We need the following to happen: One query that targets old versions of IE and one that targets modern browsers.&lt;/p&gt;

&lt;p&gt;For IE we can use &lt;code&gt;-ms-high-contrast&lt;/code&gt; (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/-ms-high-contrast"&gt;MDN&lt;/a&gt;). This could also make Edge load the styles. Luckily Microsoft deprecated the value &lt;code&gt;none&lt;/code&gt; in Edge.&lt;/p&gt;

&lt;p&gt;By including the following &lt;code&gt;link&lt;/code&gt; tag in a page, we can load styles only in old versions of IE. It works back to Windows 8.&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;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"(-ms-high-contrast: none)"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"css/ie.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, for modern browsers. Media Queries, as CSS as a whole are constantly evolving. As such there are &lt;a href="https://drafts.csswg.org/mediaqueries-4/"&gt;Media Queries Level 4&lt;/a&gt;. None of them are supported in IE. Some of them are not supported at all. In our case the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer"&gt;pointer media feature&lt;/a&gt; serves us well. &lt;/p&gt;

&lt;p&gt;As we don’t really care which pointer is used, we can query for every possible value: &lt;code&gt;(pointer: fine), (pointer: coarse), (pointer: none)&lt;/code&gt;.&lt;br&gt;
The whole link tag will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"(pointer: fine), (pointer: coarse), (pointer: none)"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"css/modern.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this combination of two output bundles and media queries we have achieved what we need: Modern features in modern browsers and old features in old ones. &lt;/p&gt;

&lt;p&gt;You can see this in action on the &lt;a href="https://playground.owlish.dev/conditional-styles/"&gt;Conditionally Load Styles demo site&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Being Pragmatic
&lt;/h2&gt;

&lt;p&gt;Making sure (some of) your code works in older browsers, does not mean &lt;em&gt;all functionality&lt;/em&gt; has to work everywhere. But, mind you, ninety percent of web development means putting text and images in boxes.&lt;/p&gt;

&lt;p&gt;And to be honest, there is no reason to not enable this everywhere. Same for form submissions. &lt;/p&gt;

&lt;p&gt;Make it boring. Make it solid. And sprinkle delight on it.&lt;/p&gt;

&lt;p&gt;Putting the blame on the users, saying «they can complete the transaction on another device», is a lazy mindset. And one that &lt;em&gt;will&lt;/em&gt; hurt your bottom line. They will not complete the task on another device. They will leave for good.&lt;/p&gt;

&lt;p&gt;In the same vein that the Web is a continuum, User Experience can be that too. If all the latest shiny technology is available, you are free to build the most amazing experience. If not, serve something that at least enabled core functionality.&lt;/p&gt;

&lt;p&gt;If we embrace these layers, we will be able to build interfaces that work in the future. As well as the &lt;a href="https://worldwideweb.cern.ch/"&gt;first web browser&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;And, as we talk about the first browser:&lt;/p&gt;

&lt;h2&gt;
  
  
  We Say Old Like It’s a Bad Thing
&lt;/h2&gt;

&lt;p&gt;We often talk about «old browser», as something to be discarded, because they are old. Seldom do we remember that these old browsers paved the way for everything we use today. This includes IE 5, the first browser to ship &lt;code&gt;XMLHttpRequest&lt;/code&gt; and complete support for CSS 1. Or Mosaic, which shipped the now ubiquitous &lt;code&gt;img&lt;/code&gt; tag (&lt;a href="https://thehistoryoftheweb.com/the-origin-of-the-img-tag/"&gt;which has a remarkable story to tell&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;I am not saying that we should all be using these browsers – or not be glad that some of the weirdness they forced upon is long gone. Still, all of these browsers managed to do one thing: keeping the continuum alive. We as people who build for the web should never forget this.&lt;/p&gt;

&lt;p&gt;And, then there are people who are sticking with one older browser. The reasons are manifold. Some don’t know how to update, some maybe don’t &lt;em&gt;want&lt;/em&gt; to upgrade.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Accessible Elephant Enters the Room
&lt;/h2&gt;

&lt;p&gt;The case against IE 11 is often justified by the fairly low percentage of people using it. And that might be true. In the grand scheme of things, anyways. And this is also where this line of reasoning gets problematic. &lt;br&gt;
What it misses is a group of users that is &lt;a href="https://ethanmarcotte.com/wrote/the-web-we-broke/"&gt;all too often dismissed while developing sites&lt;/a&gt;; users of Assisitive Technology.&lt;/p&gt;

&lt;p&gt;WebAIM regularly conducts a survey of screen readers. They published the 2019 edition in September. While the number of participants is fairly low and as as such not representative, they paint a picture that is remarkably different than «it’s only one percent and dwindling». &lt;/p&gt;

&lt;p&gt;IE 11 is the third most popular browser in the survey (&lt;a href="https://webaim.org/projects/screenreadersurvey8/#browsers"&gt;see the browser section of the results&lt;/a&gt;), used by 10 % of the respondents. The majority of the participants (85 %) are living in North America or Europe and almost half of them are 21–40 years old. This might sound like your target audience.&lt;/p&gt;

&lt;p&gt;Now, taking a look at your analytics and making an informed decision is not the worst way forward. Keep in mind, though, that your analytics are skewed towards the people already using your site. The numbers don’t tell you about the people who could never use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Never Stop Building this Way
&lt;/h2&gt;

&lt;p&gt;By broadening of definition of «support» and keeping in mind that &lt;a href="https://bradfrost.com/blog/post/support-vs-optimization/"&gt;support does not mean optimisation&lt;/a&gt;, by being thoughtful and resilient, the sites we build now will have a bright future, as well as being portable to the past. &lt;/p&gt;

&lt;p&gt;And as &lt;a href="https://worldwideweb.cern.ch/browser/#https://www.ovl.design/"&gt;my website works in the first ever browser&lt;/a&gt;, the &lt;a href="http://info.cern.ch/hypertext/WWW/TheProject.html"&gt;first ever website&lt;/a&gt; works in modern browsers.&lt;/p&gt;

&lt;p&gt;If that’s not amazing, I don’t know what is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowledgements
&lt;/h2&gt;

&lt;p&gt;Thanks to &lt;a href="https://adactio.com/"&gt;Jeremy Keith&lt;/a&gt;, &lt;a href="https://rachelandrew.co.uk/"&gt;Rachel Andrew&lt;/a&gt;, &lt;a href="https://ethanmarcotte.com/"&gt;Ethan Marcotte&lt;/a&gt;, &lt;a href="https://bradfrost.com/"&gt;Brad Frost&lt;/a&gt; and all people I’ve not linked in the text, but who wrote or spoke about building for the web and whose thoughts formed this post.&lt;/p&gt;

&lt;p&gt;Now is probably a good moment to re-read &lt;a href="https://alistapart.com/article/dao/"&gt;A Dao of Web Design&lt;/a&gt;. Nineteen years old now and as relevant as ever.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://unsplash.com/photos/uq5RMAZdZG4"&gt;Title image courtesy of NeONBRAND on Unsplash&lt;/a&gt;.&lt;/p&gt;

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