<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Marvin Danig</title>
    <description>The latest articles on Forem by Marvin Danig (@marvindanig).</description>
    <link>https://forem.com/marvindanig</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%2F31266%2F432b03c8-5cf9-4ed4-ba66-de9652787871.png</url>
      <title>Forem: Marvin Danig</title>
      <link>https://forem.com/marvindanig</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/marvindanig"/>
    <language>en</language>
    <item>
      <title> Toucaan—Baseline CSS 🎼</title>
      <dc:creator>Marvin Danig</dc:creator>
      <pubDate>Tue, 12 Nov 2019 01:21:12 +0000</pubDate>
      <link>https://forem.com/marvindanig/toucaan-baseline-css-5bc2</link>
      <guid>https://forem.com/marvindanig/toucaan-baseline-css-5bc2</guid>
      <description>&lt;p&gt;This is the second chapter on my series on &lt;a href="https://bubblin.io/blog/toucaan-introduction"&gt;Rethinking CSS Frameworks&lt;/a&gt; with Toucaan.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;❥ &lt;strong&gt;TLDR&lt;/strong&gt;; Modern web browsers have evolved to a point where a heavy-handed reset or reboot css is no longer required. In this chapter, we will implement a fundamentally different and a much lighter reset strategy by uncovering only the bare minimum set of rules that are needed for consistency according to the new &lt;a href="https://bubblin.io/blog/toucaan-introduction"&gt;landscape&lt;/a&gt; of the web. We will tackle two beasts—an intrinsically responsive layout using CSS grids and blockscoped typography, both of which in my opinion will form the basis of user interfaces (UX/UI) on the web in future.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Baselining CSS
&lt;/h2&gt;

&lt;p&gt;In the last chapter we created a &lt;a href="https://raw.githubusercontent.com/bookiza/toucaan/master/examples/example0.html"&gt;blank file&lt;/a&gt; to test the responsiveness of an empty page. That worked perfectly and was easy enough to implement. We simply touched a new file and &lt;a href="https://raw.githubusercontent.com/bookiza/toucaan/master/examples/example0.html"&gt;opened&lt;/a&gt; it on a browser like Chrome, like so:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;example0.html     // Create a new file but &lt;span class="k"&gt;do &lt;/span&gt;not write anything on it. 

&lt;span class="nv"&gt;$ &lt;/span&gt;chrome example0.html    // Open this 0 byte files on your favorite browser. 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;p&gt;Now let us take our work on the &lt;a href="https://toucaan.com"&gt;Toucaan CSS framework&lt;/a&gt; forward from this point. Let's &lt;em&gt;inspect&lt;/em&gt; this 0 byte blank page on the console of the browser. Press &lt;code&gt;⌘+⌥+I&lt;/code&gt; keys if you are on the Mac with Google Chrome:&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_LfiFWs8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/blank-page.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_LfiFWs8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/blank-page.jpg" alt="Blank web page." width="100%"&gt;&lt;/a&gt;&lt;br&gt;
  Blank webpage on the browser window.&lt;/p&gt;



&lt;p&gt;You will see that even though we loaded a blank file on to the browser, there still are a few &lt;code&gt;html&lt;/code&gt; elements that are rendered on the DOM. Every web browser will render these elements, just to display the blank page correctly. &lt;/p&gt;

&lt;p&gt;Browsers will "fix" the &lt;code&gt;html&lt;/code&gt; on page because it is in the nature of HTML to be forgiving, and modern browsers are smart enough to handle issues like missing or unmatched tags quietly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Blank page as rendered on desktop Chrome, Firefox, Brave &amp;amp; Safari. --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice that the browser also applies a default user-agent&lt;sup&gt;*&lt;/sup&gt; stylesheet called &lt;code&gt;html.css&lt;/code&gt; under the page. See the 'Styles' block (screenshot above) of your browser's console. This html.css file is a default set of rules that each browser is shipped with upon install. Up until a few years ago it was this html.css file that used to contain several inconsistencies across vendors but that is no longer the case today. &lt;/p&gt;

&lt;p&gt;We can assume that html.css—the unset cascade—itself is practically the consistent reset.css for our daily use.  &lt;/p&gt;

&lt;p&gt;A very interesting example of &lt;a rel="nofollow" href="https://hankchizljaw.com/wrote/a-modern-css-reset/"&gt;reset&lt;/a&gt; was shared by developer Andy Bell last week for a blog type of application. While their reset may be limited in scope it does help us establish the fact that there is very little arm-twisting required over a browser's own set of rules to establish consistency. This is great news and one of the main reasons why we will try and keep Toucaan a loosely coupled CSS framework for 2020.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Head over here to see what the latest &lt;code&gt;html.css&lt;/code&gt; looks like on major browsers today:&lt;/p&gt;

&lt;p&gt;Webkit html.css@ &lt;a rel="nofollow" href="https://trac.webkit.org/browser/trunk/Source/WebCore/css/html.css"&gt; Chrome &amp;amp; Safari&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quantum html.css@ &lt;a rel="nofollow" href="https://dxr.mozilla.org/mozilla-central/source/layout/style/res/html.css"&gt;Firefox&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chromium html.css@    &lt;a rel="nofollow" href="https://chromium.googlesource.com/chromium/blink/+/master/Source/core/css/html.css"&gt; Blink or Edge browser&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Getting back to the DOM, given that there are only three html elements required for a webpage to be valid, we will start with baselining Toucaan for only three baseline elements of html, namely:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. &amp;lt;html&amp;gt; tag or the **:root** element,
2. &amp;lt;body&amp;gt; tag, and the… 
3. &amp;lt;head&amp;gt; tag. 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &amp;lt;head&amp;gt; element is always set to &lt;code&gt;display:none;&lt;/code&gt;, so effectively there are only two html tags &amp;lt;body&amp;gt; and &amp;lt;html&amp;gt; for us to play with. Given below is how we will structure our baseline reset for Toucaan:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;/* The following is pure css and not sass/scss. */&lt;/span&gt;
    &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="sx"&gt;url('toucaan/portrait/portrait.css')&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;portrait&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="sx"&gt;url('toucaan/landscape/landscape.css')&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;landscape&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

    &lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;portrait&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;/* Portrait variables go here.  */&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="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;landscape&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;/* Landscape variables go here. */&lt;/span&gt; 
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;/* Bare minimum elements required for a valid webpage */&lt;/span&gt;
    &lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

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





&lt;p&gt;That's it. This is what a modern reset.css would look like on Toucaan.&lt;/p&gt;

&lt;p&gt;What it also means is that everything else that goes into designing an application, the other html elements and their corresponding styles, can be covered using optional CSS helpers to support the entire spectrum of devices and browsers. My guess is that there wouldn't be much rules to import even for the most sophisticated web applications out there, but who knows? Let us see where we can go with Toucaan before committing. &lt;/p&gt;

&lt;p&gt;Note that on the reset above I have inlined the portrait ⇋ landscape switch along with baseline tag selectors for html and body elements each and put everything inside a &lt;code&gt;&amp;lt;style&amp;gt; … &amp;lt;/style&amp;gt;&lt;/code&gt; tag. We do this to ensure that all the &lt;a rel="nofollow" href="https://css-tricks.com/annotating-critical-css/"&gt;critical&lt;/a&gt; above-the-fold &lt;a rel="nofollow" href="https://css-tricks.com/authoring-critical-fold-css/"&gt;css&lt;/a&gt; is available for the first contentful paint (FCP) as soon as possible and it helps to declare all global css variables from one place.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Some of you pointed me towards Steve Souder's article &lt;a href="http://www.stevesouders.com/blog/2009/04/09/dont-use-import/"&gt;don't use @import&lt;/a&gt; from 2009 but I can confirm that this position is no longer valid. The fact that almost 50% of the web is on http/2 and that there is a possibility of hardcaching all CSS locally using a serviceworker, I think we are good to go with imports in 2020 and beyond. Besides, our little CSS import switch will request only one external CSS file for a given 'viewport state', just like a &amp;lt;link&amp;gt; url does.&lt;/p&gt;

&lt;p&gt;Feel free to dissect the position I have taken on using CSS @imports on Toucaan but for now I am gonna happily report that &lt;strong&gt;not using CSS imports&lt;/strong&gt; to separate critical from non-critical CSS is an anti-pattern that should do be done away with. Toko, toko! &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Great, so we now have a foundation for a new reset file on Toucaan. Let us add some meat to it next. &lt;/p&gt;

&lt;h2&gt;
  
  
  Layouts with CSS Grids.
&lt;/h2&gt;

&lt;p&gt;One of the things that I'm (super!) chuffed about using for layouts on Toucaan is the CSS grids. Layouts on Toucaan are exclusively going to be based on CSS grids. Period.&lt;/p&gt;

&lt;p&gt;To enable grids we simply apply the following rule on the &lt;code&gt;body&lt;/code&gt; element of our inline-reset:&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;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&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. We are all set for &lt;em&gt;any&lt;/em&gt; kind of responsive layout with Toucaan now.&lt;/p&gt;

&lt;p&gt;Enabling grid on the body ensures that every direct child on page can now behave as part of a larger blueprint specified under a &lt;strong&gt;grid system&lt;/strong&gt;. Not only that, we can also specify different layouts for portrait and landscape switch and swap out the layout according to the new state of the viewport. &lt;/p&gt;

&lt;p&gt;I don't think there is any other way that I would do layouts in 2020.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cFJrpQVz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/css-grids.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cFJrpQVz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/css-grids.jpg" alt="Blank web page." width="100%"&gt;&lt;/a&gt;&lt;br&gt;
  Support from CSS grids is substantial in 2019.&lt;/p&gt;



&lt;p&gt;As you can see the support for CSS grids has &lt;a rel="nofollow" href="https://caniuse.com/#feat=css-grid"&gt;grown &lt;/a&gt; sufficiently with nearly every major browser having implemented the newest specification. Here is what our inline-reset with CSS grids would look:&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;style&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;/* The following is pure css and not sass/scss. */&lt;/span&gt;
    &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="sx"&gt;url('toucaan/portrait/portrait.css')&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;portrait&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="sx"&gt;url('toucaan/landscape/landscape.css')&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;landscape&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

    &lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;portrait&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;/* Portrait variables go here.  */&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="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;landscape&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;/* Landscape variables go here. */&lt;/span&gt; 
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;/* Bare minimum elements required for a valid webpage */&lt;/span&gt;
    &lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&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;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Semantic layouts! */&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

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



&lt;p&gt;We have a very simple reset.css that is grounded in the realities of the web today. In the next chapter we will move the &lt;code&gt;display: grid&lt;/code&gt; rule into its own separate class named &lt;code&gt;.layout-palette&lt;/code&gt;, which will describe how the header, the footer and the main body on a webpage will be laid out in a given context. &lt;/p&gt;

&lt;p&gt;CSS grids aren't anything new but they certainly are a new 'standards' tool that is available at our disposal. After having dabbled with CSS floats, flexbox and whatnot for years, I am convinced that CSS grids are the only logical way to do layouts. It is simple, semantic and much easier to reason about than anything else on market. &lt;/p&gt;

&lt;h4&gt;
  
  
  Why no CSS float or no flexbox? = Why CSS grids only!
&lt;/h4&gt;

&lt;p&gt;Thing is that if you want to do modern layouts in 2020 (and beyond) you shouldn't be using flexbox or floats anymore. It is just plain wrong. This of course doesn't mean that you shouldn't use flexbox or floats on your CSS at all, but using those element level properties for sitewide layouts is an anti-pattern—it is almost like a hack that we have had to live with in absence of grids. I feel very strongly about this, so let me explain this a little more: &lt;/p&gt;

&lt;p&gt;The body element on an empty webpage is like a raw piece of land waiting to be cut-up into smaller rectangles to form the foundation of a house. Each of these tiny rectangles have a different meaning or a purpose, like a kitchen or a bedroom or a living space, but are also a part of a larger blueprint of a building that is yet to be built. &lt;/p&gt;

&lt;p&gt;A set of rectangular jigsaw pieces on a website that sit next to each other in &lt;em&gt;harmony&lt;/em&gt; with shared edges. &lt;/p&gt;

&lt;p&gt;CSS grids are an ideal tool to break down this whole patch of land—the body—into smaller rectangles because it is a very top ↝ down view of the land. Whereas with flexbox you are more at the element level. Flexing is like the kitchen saying 'hey, I am a DIV and I am going to be stretching all the way leftwards to occupy whatever space is available'. Flexbox adds a certain behavior to the HTML element that needs to be counter balanced by another element (often sibling) with a behavior in the opposite direction.  &lt;/p&gt;

&lt;p&gt;It is like two little men trying to flex their muscles against each other and in process locking themselves in to form a layout. As sort of dynamic equilibrium instead of harmony. Not a very ideal situation because if the viewport were to go ultrawidescreen suddenly, the layout will fail.&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;img src="https://raw.githubusercontent.com/marvindanig/assets/master/traffic-jam.jpg" alt="Blank web page." width="100%"&amp;gt;
A soup of elements in a traffic jam.
Credit: &amp;lt;a href="https://unsplash.com/photos/o1eDaWJanpA" rel="nofollow"&amp;gt;Joline Torres&amp;lt;/a&amp;gt;, Unsplash.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Similarly, using CSS floats with a left or right momentum on the element turns a webpage into a 'traffic jam.' Almost always there is at least one element that is trying to get ahead of others. Such a layout too, like with the flexbox, is locked in a dynamic equilibrium that can easily fail on ultra-widescreens or some weird orientation towards one side. CSS floats for layouts are an absolute no-no!&lt;/p&gt;

&lt;p&gt;Not to mention the amount code required to deliver the results with floats or flexbox is almost always higher than with CSS grids. In my opinion since layout is the boundary of control, the blueprint of proportions and meaning, the basis foundation on which a house with a function will be built, it is better to use CSS grids to split the view into meaningful part that fit together naturally. &lt;/p&gt;

&lt;p&gt;Doing anything else like using the flexbox or CSS floats or tables (does anyone?) is just plain wrong. &lt;/p&gt;

&lt;h2&gt;
  
  
  Blockscoped Typography.
&lt;/h2&gt;

&lt;p&gt;The second beast that we are going to go after with Toucaan is blockscoping typography. It is possible, but before we deep dive into it, let us look at one of the common memes that gets thrown around about CSS. About how difficult it is to fit text inside a box:&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MWp7nOcA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/cssisawesome.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MWp7nOcA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/cssisawesome.png" alt="CSS is awesome!" width="66%"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;br&gt;&lt;br&gt;
  It has been traditionally been difficult to scale text within a box.&lt;/p&gt;



&lt;p&gt;Unsurprisingly, there is quite a lot of developer merchandise available out there that sells this meme printed on coffee mugs or t-shirts. I'm afraid those are gonna have to go away with the new powers of CSS. &lt;/p&gt;

&lt;p&gt;Let us first try and solve "'CSS is Awesome' in a box" problem using our portrait ⇋ landscape switch and then we'll use that solution to introduce blockscoped typography on our framework for everyone else to use. Scaling text is obviously a hard problem so I'm going to pin more on maths instead of design sense here. We will try and reconcile engineering with design principles later on. &lt;/p&gt;

&lt;p&gt;Shown below is the code I penned using our orientation switch along with some responsive typography:&lt;/p&gt;



&lt;p class="codepen"&gt;
  &lt;span&gt;See the Pen &lt;a href="https://codepen.io/marvindanig/pen/bGGRZdE"&gt;
  CSS is Awesome&lt;/a&gt; by Marvin Danig (&lt;a href="https://codepen.io/marvindanig"&gt;@marvindanig&lt;/a&gt;)
  on &lt;a href="https://codepen.io"&gt;CodePen&lt;/a&gt;.&lt;/span&gt;
&lt;/p&gt;



&lt;p&gt;Try and scale the viewport on your desktop, mobile or tablet to test it. The contents inside the box will (should) scale naturally, down to subpixel accuracy, without use of any JavaScript or special font or hardcoded CSS locks or newer properties like &lt;code&gt;clamp()&lt;/code&gt;, &lt;code&gt;minmax()&lt;/code&gt; etc. A simple orientation switch is enough to fit the text reliably. &lt;/p&gt;

&lt;p&gt;Does it 🤯 your mind? Well, it did for me! &lt;/p&gt;

&lt;p&gt;Let us look at the step-by-step solution next:&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1.
&lt;/h4&gt;

&lt;p&gt;I started with the following HTML and CSS:&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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"box"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;CSS&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;is&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;awesome.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We didn't have to separate the words into three separate lines (p tags) but it offers better control, so I did it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* CSS */&lt;/span&gt; 
&lt;span class="o"&gt;*,&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nd"&gt;:after&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nd"&gt;:before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&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="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&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="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;portrait&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;--bu&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;100vw&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="m"&gt;100&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="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;landscape&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;--bu&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;100vh&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c"&gt;/* Axiom: 100vh of landscape === 100vw of portrait. */&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;Note that we have used CSS variables to define font size according to the orientation of the viewport &lt;em&gt;and&lt;/em&gt; we are banking on the shorter side of the screen, breadth, for reliable scaling. We are thus relying on following two axioms:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Axiom 1&lt;/strong&gt;: "100vh of landscape === 100vw of portrait." &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Axiom 2&lt;/strong&gt;: The shorter side of the rectangle i.e. breadth has less potential of variation upon resizing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I must reiterate here that no special formulae or CSS locks or &lt;code&gt;clamp()&lt;/code&gt; with &lt;code&gt;minmax()&lt;/code&gt; has been used or is required to scale text accurately. Hardcoding safe values on code feels like an anti-pattern anyway, an aberration that we can avoid to align ourselves better to the idea of writing scalable software. &lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2.
&lt;/h4&gt;

&lt;p&gt;We know that the box around the text is a square, so its sides are equal. &lt;del&gt;To start I am going to use viewport width to specify dimensions of our &lt;code&gt;div.box&lt;/code&gt; inside the portrait part of our orientation switch:&lt;/del&gt; I set the sides of the square to 50% of breadth by using 50 bu's (&lt;em&gt;breadth units&lt;/em&gt;), where each &lt;code&gt;--bu&lt;/code&gt; css variable defined on the &lt;code&gt;:root&lt;/code&gt; element stands for the viewport width or height depending on device orientation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;*,&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nd"&gt;:after&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nd"&gt;:before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&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="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&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="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;portrait&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;--bu&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;100vw&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="m"&gt;100&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="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;landscape&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;--bu&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;100vh&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c"&gt;/* 100vh of landscape === 100vw of portrait. */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.box&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&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="n"&gt;arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&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="nl"&gt;width&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;50&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;--bu&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;    &lt;span class="c"&gt;/* 50% of breadth */&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;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50&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;--bu&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nl"&gt;border&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;2&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;--bu&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&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;/* Simple blockscoped typography based on breadth of the rectangle . */&lt;/span&gt;
&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&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&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;50&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;--bu&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;              &lt;span class="c"&gt;/* 25% of the width of the box. */&lt;/span&gt;
    &lt;span class="nl"&gt;line-height&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.25&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;50&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;--bu&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;     &lt;span class="c"&gt;/* Line height = 1.25 */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&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;50&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="m"&gt;4&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;--bu&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nl"&gt;line-height&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.25&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="m"&gt;4&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;--bu&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="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&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;50&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="m"&gt;6&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;--bu&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nl"&gt;line-height&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.25&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="m"&gt;4&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;--bu&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c"&gt;/* Required on Codepen: */&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;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;-webkit-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&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="nl"&gt;justify-content&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;h4&gt;
  
  
  Step 3.
&lt;/h4&gt;

&lt;p&gt;Great, so now we have square with width and height of &lt;code&gt;calc(50 * var(--bu))&lt;/code&gt;. This is the 100% width or height of the box. To blockscope typography inside the box, we will use the dimensions of the box to arrive at text sizing elements like font-size and line-height, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* 25% of the width of the box. */&lt;/span&gt;
&lt;span class="nt"&gt;font-size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;4&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;50&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;--bu&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;

&lt;span class="c"&gt;/* Line height = 1.25 times font size */&lt;/span&gt;
&lt;span class="nt"&gt;line-height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;25&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;4&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;50&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;--bu&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;       
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's it. &lt;/p&gt;

&lt;p&gt;The text in the box will now scale responsively with subpixel accuracy as the browser is resized or the orientation is changed. Scaling is so accurate that even reflow isn't be triggered in 99% of the time!&lt;/p&gt;

&lt;p&gt;Ala, welcome to &lt;strong&gt;blockscoped responsive typography&lt;/strong&gt; with Toucaan. 😎&lt;/p&gt;

&lt;p&gt;Feel free to test the &lt;a rel="nofollow" href="https://codepen.io/marvindanig/full/bGGRZdE"&gt;demo&lt;/a&gt; by resizing your browser to its extremes and by going on any device between an Apple Watch 5 to OLED TVs. Report &lt;a rel="nofollow" href="https://github.com/bookiza/toucaan/issues"&gt;issues&lt;/a&gt; on Github if you bump into one. &lt;/p&gt;

&lt;p&gt;Given that there is so much that can happen with typefaces I'll keep my ideas about blockscoped typography in an evaluative mode for now. It is yet to be seen if Toucaan can nail intrinsic layouts with blockscoped typography, especially for some more complex layouts. So look out for another chapter on this topic soon!&lt;/p&gt;




&lt;h3&gt;
  
  
  A note about vocabulary in use today:
&lt;/h3&gt;

&lt;p&gt;Height and width is how we usually refer to the dimensions of a screen or the browser window. But what we are doing here, in mathematical speak, is referring to a simple rectangle with a length and a breadth. The labels height and width are all but an accurate description in the context of the desktop. Where the monitor is mounted in a way that the contents are displayed along the vertical plane. But height and with become somewhat invalid as soon as we start surfing content on a mobile or a tablet that is not held up vertically.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--npYLrViw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/rectangles.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--npYLrViw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/rectangles.jpg" alt="Portrait or landscape rectangles." width="100%"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;br&gt;&lt;br&gt;
  &lt;br&gt;&lt;br&gt;
  Use length &amp;amp; breadth instead of height &amp;amp; width?&lt;/p&gt;



&lt;p&gt;One could be lying down on a sofa looking up towards the ceiling into the phone. Or looking down on a tablet lying flat on a desk, meaning parallel to the floor. Since the screen is no longer restricted to displaying content along the vertical plane, using height and width to specify its dimensions isn't always a 100% accurate. Labeling it with length and breadth however will be, no matter what the orientation of the screen is. 🤯 &lt;/p&gt;

&lt;p&gt;*For sake of clarity on Toucaan I'll often use mathematical labels &lt;em&gt;length&lt;/em&gt; and &lt;em&gt;breadth&lt;/em&gt; instead of height and width to refer to the dimensions of the rectangular display. There is an added advantage of doing this—we exactly know that the shorter side of the rectangle &lt;em&gt;is&lt;/em&gt; the breadth, which could be viewport width or viewport height depending on orientation.&lt;/p&gt;






&lt;h2&gt;
  
  
  The final reset:
&lt;/h2&gt;

&lt;p&gt;This is what our final &lt;code&gt;reset.css&lt;/code&gt; on Toucaan looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;/* Modern reset using CSS Grids for layouts,    */
/* a typography pallete with block scopes and   */
/* a few accessibility-first media queries.     */

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;@charset&lt;/span&gt; &lt;span class="s1"&gt;"UTF-8"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c"&gt;/* Recommended reading: https://www.w3.org/International/questions/qa-css-charset.en */&lt;/span&gt;

    &lt;span class="c"&gt;/* Option 1. Use system fonts */&lt;/span&gt;

    &lt;span class="c"&gt;/* Option 2. Use 'privacy safe' self-hosted typefaces with subsetting, or use…  */&lt;/span&gt;
    &lt;span class="k"&gt;@font-face&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="s1"&gt;"Font Family"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url(data:font/opentype;base64, _font_subsetted_string_)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
        &lt;span class="nl"&gt;font-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;/* Option 3. Hosted typefaces such as from Google Fonts. */&lt;/span&gt;
    &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="sx"&gt;url(https://fonts.googleapis.com/css?family=Font+Family:300,300i&amp;amp;display=swap)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

    &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="sx"&gt;url('toucaan/portrait/portrait.css')&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;portrait&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="sx"&gt;url('toucaan/landscape/landscape.css')&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;landscape&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

    &lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;portrait&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;--bu&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;100vw&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;/* Tentative */&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="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;landscape&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;--bu&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;100vh&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c"&gt;/* Tentative */&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;/* Sane defaults below */&lt;/span&gt;&lt;span class="nt"&gt;s&lt;/span&gt;
    &lt;span class="o"&gt;*,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nd"&gt;:after&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nd"&gt;:before&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c"&gt;/* I have a feeling that using margin &amp;amp; padding on elements instead */&lt;/span&gt;
        &lt;span class="c"&gt;/* of the flexbox is somewhat an anti-pattern now but I am not sure. */&lt;/span&gt;
        &lt;span class="c"&gt;/* We will come back to this topic in sometime. */&lt;/span&gt;
        &lt;span class="nl"&gt;margin&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="nl"&gt;padding&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="nt"&gt;html&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="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Always set the background color */&lt;/span&gt; 
        &lt;span class="nl"&gt;-moz-osx-font-smoothing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grayscale&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;-webkit-font-smoothing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;antialiased&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;overflow-x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;overflow-y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;scroll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="py"&gt;text-size-adjust&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c"&gt;/* Move this into font-family. */&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;4&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;--bu&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c"&gt;/* Theoretical a.t.m */&lt;/span&gt;
        &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Font Family'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;system-ui&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;-apple-system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BlinkMacSystemFont&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Segoe&lt;/span&gt; &lt;span class="n"&gt;UI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Roboto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Oxygen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Ubuntu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Cantarell&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Droid&lt;/span&gt; &lt;span class="n"&gt;Sans&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Helvetica&lt;/span&gt; &lt;span class="n"&gt;Neue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fira&lt;/span&gt; &lt;span class="n"&gt;Sans&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="py"&gt;font-smooth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   
        &lt;span class="nl"&gt;font-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;font-synthesis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;font-stretch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;ultra-condensed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;font-variant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;no-common-ligatures&lt;/span&gt; &lt;span class="n"&gt;proportional-nums&lt;/span&gt; &lt;span class="n"&gt;slashed-zero&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;font-kerning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;text-rendering&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;geometricPrecision&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Why not: text-rendering: optimizeSpeed;?… in light of PWA. */&lt;/span&gt;
        &lt;span class="py"&gt;font-display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="py"&gt;font-display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nl"&gt;-webkit-tap-highlight-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&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="m"&gt;0&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="nl"&gt;-webkit-backface-visibility&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nl"&gt;-webkit-font-smoothing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;subpixel-antialiased&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;-moz-osx-font-smoothing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grayscale&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;-webkit-osx-font-smoothing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;antialiased&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


        &lt;span class="nl"&gt;line-height&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.5&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;4&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;--bu&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;  &lt;span class="c"&gt;/* Or 1.5 */&lt;/span&gt;

        &lt;span class="c"&gt;/* Colors + contrast (This will go into the color palette.) */&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;rgba&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="m"&gt;0&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="m"&gt;0.95&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="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c"&gt;/* Dimensions */&lt;/span&gt;
        &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&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;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


        &lt;span class="c"&gt;/* Behavior */&lt;/span&gt;
        &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;-webkit-overflow-scrolling&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;touch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="py"&gt;scroll-behavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;smooth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="py"&gt;touch-action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Grids are meant for layouts, flex are meant for element behavior! */&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;



    &lt;span class="c"&gt;/* Accessibility specific media queries go below. */&lt;/span&gt;

    &lt;span class="c"&gt;/* 1. Dark mode (or light) depending on requirement. */&lt;/span&gt;
    &lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&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="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="m"&gt;#343434&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="m"&gt;#fff&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;/* 2. Override animations for users with motion sickness or other vestibular disorders. */&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-reduced-motion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;)&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="nl"&gt;animation-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.01ms&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;animation-iteration-count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;transition-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.01ms&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="py"&gt;scroll-behavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt; &lt;span class="cp"&gt;!important&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="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

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



&lt;p&gt;Welcome to intrinisically scalable layouts using CSS grids, responsive blockscoped typography and an orientation based design behavior separated along &lt;code&gt;portrait&lt;/code&gt; &amp;amp; &lt;code&gt;landscape&lt;/code&gt; css to gracefully adapt according to the new landscape of the web. &lt;/p&gt;

&lt;p&gt;We will refactor the above shown reset with more explanatory notes in the future chapters. Onwards to typesetting and more CSS grids in the next chapter!&lt;/p&gt;

&lt;p&gt;I have updated the &lt;a href="https://github.com/bookiza/toucaan"&gt;Toucaan&lt;/a&gt; repository with this article and the latest code. Please note that everything on this repo is currently experimental in nature, so feel free to question, star, jump-in or offer sage advice. Contributions to Toucaan are also super welcome. &lt;em&gt;Toko, toko!&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Written by: Marvin Danig, CEO &amp;amp; Cofounder of Bubblin Superbooks. Follow me on &lt;a href="https://twitter.com/marvindanig"&gt;Twitter&lt;/a&gt; or &lt;a href="https://github.com/marvindanig"&gt;Github&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;I am super thankful to &lt;a href="https://bubblin.io/sonica-sonica-arora"&gt;Sonica Arora&lt;/a&gt;, Satyendra Sharma and Abigail Rennemeyer for the edits and helping me check the code for accuracies.&lt;/p&gt;

</description>
      <category>css</category>
      <category>responsive</category>
      <category>reset</category>
      <category>baseline</category>
    </item>
    <item>
      <title>Toucaan—Rethinking CSS Frameworks. 📖</title>
      <dc:creator>Marvin Danig</dc:creator>
      <pubDate>Thu, 17 Oct 2019 15:57:06 +0000</pubDate>
      <link>https://forem.com/marvindanig/toucaan-rethinking-css-frameworks-394p</link>
      <guid>https://forem.com/marvindanig/toucaan-rethinking-css-frameworks-394p</guid>
      <description>&lt;p&gt;[Last update: October, 12&lt;sup&gt;th&lt;/sup&gt; 2019.]&lt;/p&gt;

&lt;p&gt;&lt;em&gt;❥ &lt;strong&gt;TLDR&lt;/strong&gt;; This is the first of the many chapters on a new CSS framework called &lt;a href="http://toucaan.com"&gt;Toucaan&lt;/a&gt;. In this introductory post we talk about the new landscape of the web, consider miniature viewports like that of the Apple Watch 5 and the new Chromium based surface (V9 web browser) on a Tesla Model 3 and Model S as part of the web. Form factors available today are so diverse and different from barely four years ago that design strategies of the past such as "mobile first" or barely responsive are no longer viable. The slate of glass is resizable practically on a continuum, just like the web browser itself.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Modern web browsers too have evolved and gotten so much better that we no longer need a heavy-handed approach to force consistency across vendors. With Toucaan we will try to move away from traditional reset or reboot css and implement a simpler and lighter strategy instead. So, welcome to Toucaan—a tropical new CSS framework for the web, with fewer defaults, newer patterns and a much simpler cascade.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This chapter is available on a &lt;a href="https://bubblin.io/cover/the-toucaan-framework-by-marvin-danig#frontmatter"&gt;book&lt;/a&gt; that you can preorder. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;2020 is almost here.&lt;/p&gt;

&lt;p&gt;It is unlikely that you or I are going to blast off to Mars or the Moon on a &lt;a rel="nofollow noreferrer noopener" href="https://www.spacex.com/starship"&gt;Spacex Starship&lt;/a&gt; anytime soon so we better turn our gaze towards another frontier of technology: CSS. 🙃&lt;/p&gt;

&lt;p&gt;Let's take a look at how we will be writing web applications in 2020 and beyond, here on Earth. &lt;/p&gt;

&lt;p&gt;Through this post we will revisit the basics of a web page, i.e. HTML &amp;amp; CSS, and develop a clean, intelligent and maintainable CSS framework from scratch. I named our new CSS framework &lt;a href="https://toucaan.com"&gt;Toucaan&lt;/a&gt; and you can join me on the journey of building it together. Here is its official &lt;a href="https://github.com/bookiza/toucaan"&gt;repository&lt;/a&gt; and a silly Toucan logo that I made using CSS.&lt;/p&gt;



&lt;p&gt;&lt;a href="http://toucaan.com"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IDH69j4G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/bookiza/toucaan/master/toucaan.svg%3Fsanitize%3Dtrue" alt="Toucaan-A Tropical CSS Framework" width="400"&gt;&lt;/a&gt;&lt;br&gt;
  &lt;/p&gt;
&lt;h2&gt;The Tropical CSS Framework.&lt;/h2&gt;



&lt;p&gt;Qualitatively speaking, the intent of Toucaan is to weed out all the unwanted CSS that your webapp doesn’t need. It is a deep dive into core CSS properties and web standards in a bid to discover new and useful patterns according to the new landscape of the web. We might identify a few anti-patterns in the process that our industry may currently be plagued with too, but we can address those on-the-fly as we go about building Toucaan ground up.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why call it Toucaan?
&lt;/h4&gt;

&lt;p&gt;Well, quite simply because I owned the pretty domain name. &lt;/p&gt;

&lt;p&gt;Besides, Toucan is a beautiful bird. This aggressive little arboreal ramphastidus symbolizes both beauty and strength. We are going to base our CSS framework on this highly social and resilient bird to implement a styling stricture that will cover all the wilderness on the web. Ocassionally—though rarely—we may even spar with other CSS frameworks using our "mean" oversized and colorful bill. &lt;/p&gt;

&lt;p&gt;So—say hello to &lt;strong&gt;Toucaan&lt;/strong&gt;—the tropical CSS framework for the web. 😉&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[&lt;em&gt;Say it aloud&lt;/em&gt;:] CSS may be hard but… &lt;strong&gt;if Tou-caan, then you-can-too!&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hhb-aIaE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/charlesbabbage.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hhb-aIaE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/charlesbabbage.jpg" width="100%"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;With Toucaan we will revisit every web design and layouting principle that there is. Test our ideas out in the open. No trick or technique, whether old or new is off the table, but we will definitely try to avoid using hacks. There are few other rules that Toucaan will adhere to and those are described &lt;a href="https://github.com/bookiza/toucaan"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now there are a lot of well established CSS frameworks out there like the Bootstrap, Bulma, Foundation, TailwindCSS and a bunch of strategies like the BEM, OOCSS or SMACSS (and others) to organize the application code but we will not try to imitate or wrestle with those. We will rather write Toucaan on a blank slate and in such a way that we do not take away anything from what most of these tools have to offer finally, but we add more to what's on the table for everyone to consider and use on production. &lt;/p&gt;

&lt;p&gt;Let's begin.&lt;/p&gt;

&lt;h1&gt;
  
  
  The New Landscape of Web
&lt;/h1&gt;

&lt;p&gt;Before we write our first line of code let us take a deep breath and look at the variety of devices that are a part of the web today. With subtle differences in their aspect ratios, device handling &amp;amp; user behavior, browser support and screenwise capabilities it is important to understand what the new landscape of the web looks like today and understand exactly what we are up against for a new CSS framework of 2020.&lt;/p&gt;

&lt;p&gt;Here are some of the devices that sport a modern web browser:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ItO8LYB8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/major-devices.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ItO8LYB8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/major-devices.png" alt="Major web devices." width="100%"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---JHDrcm6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/web-devices.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---JHDrcm6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/web-devices.png" alt="Major web devices." width="100%"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is the Apple Watch 5 with a web browser, iPhones in numerous sizes instead of just one model that Apple used to come up with earlier, multiple iPads, iPad Pros and Android tablets plus desktops, laptops and TV sets with a stock browser that work surprisingly well. Given that Samsung came out with a foldable phone recently and Microsoft is probably coming out with a foldable Surface tablet very soon, it is safe to assume that physical form is no longer a reliable viewport classifier that is so commonly used by every other framework.  &lt;/p&gt;

&lt;p&gt;It is rather safe to assume that screen-sizes are available on a &lt;strong&gt;linear continuum&lt;/strong&gt; of form-factors and that a large phone could easily be considered a phablet or a tablet could easily become more than a desktop and so on depending on hardware and options. Whereas there is a large variation in the form factors available on the web, there is also substantial variation in the way each surface exposes the controls and input methods to the user—ala, accessibility over content. Let's not forget that there are cars too on the web now—in that they sport a neat web browser for those who need to be online while being on road. And then there are low-powered devices on the budget end of the market, like the Nokia 2.2 on Android (A53 core) or similar that are very popular in their segment as well. &lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tQYhkuka--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/tesla-falcon.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tQYhkuka--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/tesla-falcon.png" alt="Major web devices." width="50%"&gt;&lt;/a&gt;&lt;br&gt;
  Credit: Stuart O'Neil, The Noun Project.&lt;/p&gt;



&lt;p&gt;Since Toucaan is about living CSS a short distance into the future, we will consider the V9 web browser from Tesla into the scope of our project as well. This is something that I have been meaning to do for sometime and given that people would have nothing to do but surf the web or &lt;a href="https://bubblin.io"&gt;read a book&lt;/a&gt; in a car that's driving itself, this seems like a reasonable thing to do.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r1lwdOCJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/tesla-web-browser.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r1lwdOCJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/tesla-web-browser.png" alt="Major web devices." width="100%"&gt;&lt;/a&gt;&lt;br&gt;
  Web is way bigger than it ever was. &lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A cool trivia&lt;/strong&gt;: I wanted to publish this article three years ago but the rate of change in industry kept me from doing so. With new features being rolled out every week it was hard to track changes and decide on a strategy. CSS grids, ES6 and the whole reactive developer toolchain thing (I am looking at you, the noisy folks of React &amp;amp; Vue.JS!) followed by Apple &amp;amp; Google announcing the non-rectangular &lt;a href="https://bubblin.io/blog/notch"&gt;notched phones&lt;/a&gt; and so on. Web is enormous now, and it is much harder to design and scale websites between the lowest and the highest options that there are.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notice that we are not even into talking about web browsers yet and yet the range of hardware itself is  diverse enough to somewhat trump the very first assumption taken by nearly all the existing frameworks: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Hardcoded break point values using CSS @media-queries"&lt;/strong&gt;. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Voila, we have our first &lt;strong&gt;anti-pattern&lt;/strong&gt; to go after now! ( ͡° ͜ʖ ͡°)&lt;/p&gt;

&lt;h2&gt;
  
  
  What's with the hardcoded break points, eh?
&lt;/h2&gt;

&lt;p&gt;Breakpoints are hardcoded on Tailwind CSS like this [&lt;a href="https://tailwindcss.com/docs/theme#screens"&gt;1&lt;/a&gt;, &lt;a href="https://tailwindcss.com/docs/breakpoints/"&gt;2&lt;/a&gt;], for example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// tailwind.config.js&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;screens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;640px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Translates to hardcoded break-points in media queries.&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;md&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;768px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1024px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1280px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;On Bulma, the break points [&lt;a href="https://github.com/jgthms/bulma/blob/49708a36a1f88870ec19db74888acc526a4188f3/css/bulma.css#L497"&gt;1&lt;/a&gt;] are used to silo blocks of code similarly like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Bulma CSS like any other framework uses hardcoded breakpoints like so: */&lt;/span&gt; 

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;768px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;/* Some style classes &amp;amp; rules here. */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&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;769px&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;/* Same classNames but different rules here. */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1023px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;/* We armtwist the ruleset again… */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&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;1024px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;/* Are we on the desktops now? */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&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;1216px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;/* Dang!, what are we supporting here? */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&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;1408px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;/* Is this the iPad Pro 12.9 inches or something else? */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then for each silo elsewhere on the CSS…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;mobile&lt;/span&gt;
  &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;typography-size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;'mobile'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;tablet&lt;/span&gt;
  &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;typography-size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;'tablet'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;touch&lt;/span&gt;
  &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;typography-size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;'touch'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;desktop&lt;/span&gt;
  &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;typography-size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;'desktop'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;widescreen&lt;/span&gt;
  &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;typography-size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;'widescreen'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;fullhd&lt;/span&gt;
  &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nt"&gt;typography-size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;'fullhd'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;…hundreds of &lt;code&gt;classNames&lt;/code&gt; are repeated to cater to the behavior desired in each silo of devices. Pretty much every CSS framework follows this pattern and a breakpoint is added every few years to account for industry-level changes. The question is how many hardcoded breakpoints will we continue to add as our industry evolves at a break-neck speed? &lt;/p&gt;

&lt;p&gt;At what point will the hardcoded breakpoints become all too many? &lt;/p&gt;

&lt;h4&gt;
  
  
  Mode driven instead of data driven:
&lt;/h4&gt;

&lt;p&gt;While it would be a nice exercise to plot a graph of all the screen sizes (pixel ratio data) that are available on market, but going down this path to figure out a new set of breaking point values to separate mobile from tablets from watches from desktops from cars to any other new kind of surface that is about to come on the web is anything but scalable. Or even practical. &lt;/p&gt;

&lt;p&gt;In my opinion using hardcoded values on CSS media queries is an artifact of the tunnel vision of mobile web that we have held since the very first iPhone. It is rather a simplistic solution of a simpler time that is no longer valid, and &lt;em&gt;therefore&lt;/em&gt; an anti-pattern that we should move away from. We need something  smarter to handle the diversity of web devices now.&lt;/p&gt;

&lt;p&gt;So, is there a way to implement layout responsively without using hardcoded break-points? &lt;/p&gt;

&lt;p&gt;Turns out, yes there is! &lt;/p&gt;

&lt;p&gt;We can build any kind of responsive application using a really simple and smart set of rules that we will talk about in the next section.&lt;/p&gt;

&lt;h1&gt;
  
  
  The 'Two States' of Web Design.
&lt;/h1&gt;

&lt;p&gt;Let's create a &lt;a href="https://raw.githubusercontent.com/bookiza/toucaan/master/examples/example0.html"&gt;blank page&lt;/a&gt; on your machine and load it on a desktop browser first. &lt;/p&gt;

&lt;p&gt;This is easy, simply jump into your terminal and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;example0.html     // Create a new file but &lt;span class="k"&gt;do &lt;/span&gt;not write anything on it. 

&lt;span class="nv"&gt;$ &lt;/span&gt;chrome example0.html    // Open this 0 byte files on your favorite browser. 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What do you see on this blank page? &lt;/p&gt;

&lt;p&gt;Of course nothing, it is an all-white or an all-black blank page depending on your browser's defaults. Did you know that this blank web page is the &lt;em&gt;most&lt;/em&gt; responsive web page in the whole world wide web? &lt;/p&gt;

&lt;p&gt;No CSS or media query is required to adapt the UX/UI of a blank page on mobile or desktop or any other device on web. You can resize the browser to any aspect ratio and the blank web page will continue to scale perfectly and responsively.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5ueDZjFo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/viewports.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5ueDZjFo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/viewports.png" alt="Major web devices." width="66%"&gt;&lt;/a&gt;&lt;br&gt;
  Viewport rectangles of the browser window on resize.&lt;/p&gt;



&lt;p&gt;Well, of course a blank page is going to be responsive you'd say but this is a hypothetical situation Marvin, so let's turn the table over and orient the desktop in portrait mode instead:&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YMCpSmAv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/desktop-portrait-landscape.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YMCpSmAv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/marvindanig/assets/master/desktop-portrait-landscape.png" width="100%"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Now the desktop in portrait orientation is going to reveal a browser window that is longer in height and shorter in width—kind of like a mobile phone but on a much bigger piece of glass. In reality a very small group of people use desktops in portrait mode (mostly developers) but the usage is possible nevertheless. Use of portrait mode grows on tablets—with about 60% iPad users preferring landscape over portrait where as the story flips completely on a smartphone where about ~96% people prefer the portrait mode over landscape depending on content. With Apple Watch, the tiniest of screens on web, I suspect that nearly 100% of usage would be in portrait mode given that the device is physical tied to the wrist that way. &lt;/p&gt;

&lt;p&gt;Here are some &lt;a href="https://ux.stackexchange.com/questions/64749/are-ipads-used-horizontally-or-vertically"&gt;graphs &amp;amp; stats&lt;/a&gt; if you're interested.&lt;/p&gt;

&lt;p&gt;On Tesla Model S the browser open in portrait orientation just like a desktop in portrait mode while on Model 3 it does so in landscape mode. Well this discussion kind of uncovers that all of the web is viewed in only two modes of orientation—portrait or landscape—and square is the geometric point of inflexion where the media query needs to switch from portrait to landscape and vice-versa. Interesting.&lt;/p&gt;

&lt;p&gt;This also means that there are only &lt;strong&gt;two states of design&lt;/strong&gt; on web no matter which device or orientation one may choose to consume web on. It is a hard cold fact that electronic screens are rectangular in shape—well, &lt;a href="https://bubblin.io/blog/notch"&gt;almost&lt;/a&gt;—and therefore, the point of inflexion for all style rules to switch mode should be where the viewport itself becomes a square and starts flexing in the other direction. Since there are hardly any devices in shape of a perfect square, mathematically speaking we can take it for granted that a webpage will either render in &lt;code&gt;portrait&lt;/code&gt; mode or &lt;code&gt;landscape&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;And oh, oh, ICYMI, there is a lot more &lt;code&gt;math&lt;/code&gt; coming into CSS in the near future so we'll have trigonometry at our disposal eventually!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;blockquote class="twitter-tweet" data-lang="en"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The CSS Working Group agreed this morning on adding many math functions. We now have:&lt;br&gt;&lt;br&gt;• calc()&lt;br&gt;• min()&lt;br&gt;• max()&lt;br&gt;• clamp()&lt;br&gt;• sin()&lt;br&gt;• cos()&lt;br&gt;• tan()&lt;br&gt;• acos()&lt;br&gt;• asin()&lt;br&gt;• atan()&lt;br&gt;• atan2()&lt;br&gt;• hypot()&lt;br&gt;• sqrt()&lt;br&gt;• pow()&lt;br&gt;&lt;br&gt;The face of CSS is rapidly changing.&lt;/p&gt;— Benjamin De Cock (@bdc) &lt;a href="https://twitter.com/bdc/status/1100921258839953408?ref_src=twsrc%5Etfw"&gt;February 28, 2019&lt;/a&gt;

    



&lt;h2&gt;
  
  
  Kickstarting the code
&lt;/h2&gt;

&lt;p&gt;Now that we have covered some ground for Toucaan to work on let's start wiring up all the ideas discussed above into code. Since a webpage can be rendered in only one of the two states of the viewport, either portrait or landscape, we'll begin with the following ruleset for our new framework:&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="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;portrait&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;/* Portrait variables go here.  */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 

  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="sx"&gt;url('toucaan/portrait/portrait.css')&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;portrait&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="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;landscape&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;/* Landscape variables go here. */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="sx"&gt;url('toucaan/landscape/landscape.css')&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;landscape&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 twin code blocks above may not seem like much at this stage but this dual state switch is exactly what we are going to use to go about scaling our layout across all the web devices on the planet. Notice that we are using a standard asynchronous @import call to request only so much CSS that a given "viewport state" will require. On the desktop, this state of a given render will not change unless the browser window is resized or if the user decides to swivel the monitor over.&lt;/p&gt;

&lt;p&gt;Organizing your CSS this way ensures that both "states" of every element that will render on the DOM have been considered and then we can be sure that the webpage will scale desirably across the entire spectrum of devices that are on the web. It also helps avoiding a gigantic &lt;code&gt;reset.css&lt;/code&gt;/&lt;code&gt;reboot.css&lt;/code&gt; which can be a pain on low-powered devices. So hang in there for a little bit and stand by for the next chapter on Toucaan in which we will take up baselining CSS across vendors and introduce scalable responsive typography without use of javascript. &lt;/p&gt;

&lt;p&gt;I have setup a tiny repository for &lt;a href="https://github.com/bookiza/toucaan"&gt;Toucaan&lt;/a&gt; and checked-in all that is under experimentation right now. Feel free to star, jump-in, offer sage advice or contribute to Toucan!&lt;/p&gt;




&lt;p&gt;Written by: Marvin Danig, CEO &amp;amp; Cofounder of Bubblin Superbooks. Follow me on &lt;a href="https://twitter.com/marvindanig"&gt;Twitter&lt;/a&gt; or &lt;a href="https://github.com/marvindanig"&gt;Github&lt;/a&gt; perhaps?&lt;/p&gt;

&lt;p&gt;Super thankful to &lt;a href="https://bubblin.io/sonica"&gt;Sonica Arora&lt;/a&gt;, Abigail Rennmeyer, Varun Singh and &lt;a rel="nofollow noopener" href="https://nilesh.trivedi.pw/"&gt;Nilesh Trivedi&lt;/a&gt; for helping me review this post for accuracies.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article was originally published at &lt;a href="https://bubblin.io/blog/toucaan-introduction"&gt;Bubblin&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>design</category>
      <category>css</category>
      <category>responsive</category>
      <category>web</category>
    </item>
    <item>
      <title> To Serif or Not To (Sans) Serif?</title>
      <dc:creator>Marvin Danig</dc:creator>
      <pubDate>Thu, 20 Jun 2019 19:38:47 +0000</pubDate>
      <link>https://forem.com/marvindanig/to-serif-or-not-to-sans-serif-210c</link>
      <guid>https://forem.com/marvindanig/to-serif-or-not-to-sans-serif-210c</guid>
      <description>&lt;p&gt;Usually when I'm tired of coding I look up to design. &lt;/p&gt;

&lt;p&gt;Art is pleasing to the eyes and it helps me take my mind off development whenever I can. This time around I decided to dive into typography to understand what kind of typefaces look good on the books that we publish on &lt;a href="https://bubblin.io" rel="noopener noreferrer"&gt;Bubblin&lt;/a&gt;, and why?&lt;/p&gt;

&lt;p&gt;To serif or not to (sans) serif, that is the question.&lt;/p&gt;

&lt;p&gt;When it comes to web typography, this is a settled &lt;a href="https://www.urbanfonts.com/blog/2013/02/serif-vs-sans-the-final-battle/" rel="nofollow noopener noreferrer"&gt;battle&lt;/a&gt; more or less. That if you're designing for web use sans serif typography but if you are designing for print go for serif typefaces that compel authority over minimalism. That &lt;a href="http://alexpoole.info/blog/which-are-more-legible-serif-or-sans-serif-typefaces/" rel="nofollow noopener noreferrer"&gt;adage&lt;/a&gt; about what works on the web and what doesn't, and vice-versa. &lt;/p&gt;

&lt;p&gt;But the question is, again, &lt;em&gt;why&lt;/em&gt;? &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Why do sans serif typefaces work better on web but not the serif ones?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Why do the flourishes of serif fonts compel class and authority on print books? &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Goes without saying here that following the design guidelines (such as to use sans serif typefaces on the web) is critical for inclusivity. &lt;/p&gt;

&lt;p&gt;Always design for the form and function both. &lt;/p&gt;

&lt;p&gt;Through this post we will look at some of the reasons why the guidelines in the first place and how we can typeset our website correctly for accessibility.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The best font choices are those where readers notice the message."&lt;/p&gt;
&lt;/blockquote&gt;






&lt;p&gt;Let's take a look at the anatomy of a typeface first:&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmarvindanig%2Fassets%2Fmaster%2Fanatomy-of-typography.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%2Fraw.githubusercontent.com%2Fmarvindanig%2Fassets%2Fmaster%2Fanatomy-of-typography.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;
        [ Image credit:
        &lt;a href="https://www.designersinsights.com/designer-resources/anatomy-of-typography/" rel="nofollow noopener noreferrer"&gt; Designer Insights &lt;/a&gt;]



&lt;br&gt;
&lt;br&gt;

Serifs are those decorative flourishes at the end of the strokes.

As you can see from the anatomy above, `serif` typefaces look fancier and well-decorated, but their flourishes work only at a sufficiently large size. When the typeface is shrunk below a certain threshold, these flourishes turn into noise and lower overall legibility—meaning, they do not help our ability to recognize individual letters or words at speed, thus affecting visual accessibility. 

&amp;gt; Serifs are used to guide the horizontal “flow” of the eyes; The lack of serifs is said to contribute to a vertical stress in sans serifs, which is supposed to compete with the horizontal flow of reading. – [De Lange et al., 1993](http://cajun.cs.nott.ac.uk/compsci/epo/papers/volume6/issue3/rudi.pdf).

Before we take up what _"flow" of the eyes_ is here and how _vertical stress_ helps with readability on web, let's step away from typography for a moment and take a look at animation first. 

---

Yes, a typical animation film from Disney or Pixar, for example.


Animation is storytelling as a function of time. 

In other words time is the glue between storytelling and the motion of story i.e. flow. You may be surprised that this motion or flow of story can be depicted on a single shot of frame as well. Look at Lightning McQueen below, for example:

It's a still picture but there is motion in it too. 

&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmarvindanig%2Fassets%2Fmaster%2Fmcqueen.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%2Fraw.githubusercontent.com%2Fmarvindanig%2Fassets%2Fmaster%2Fmcqueen.jpg"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
        [ Image credit:
        &lt;a href="https://en.wikipedia.org/wiki/Cars_(film)" rel="nofollow noopener noreferrer"&gt; Cars Movie @Pixar &lt;/a&gt;]
    &lt;/p&gt;



&lt;p&gt;Notice the blurred alphabets 'E' and 'D' on the side of the race track that suggest McQueen is speeding through the frame. This blurring is called motion blur or pan blur depending on how the camera or the subject moved and left behind a trail as the frame was being captured. Those hazy attributes stretching E &amp;amp; D alphabets represent the flow of time, they hint us about movement, its direction and speed.&lt;/p&gt;

&lt;p&gt;Below is another picture of Tibetan wild asses running amok in Ladakh.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmarvindanig%2Fassets%2Fmaster%2Ftibetan-wildass.jpeg" 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%2Fraw.githubusercontent.com%2Fmarvindanig%2Fassets%2Fmaster%2Ftibetan-wildass.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;
        [ Image credit:
        &lt;a href="https://bubblin.io/book/ladakh-by-satie-sharma/137" rel="noopener noreferrer"&gt; Satyendra Sharma&lt;/a&gt;]&lt;/p&gt;



&lt;p&gt;On this picture you can see that the animals are running forward but their heads are bobbing up and down too. Even though the picture is hazy, and the attributes of the animals aren't very clear, but the motion is evident from a single shot due to &lt;a href="https://en.wikipedia.org/wiki/Saccadic_masking#Intrasaccadic_perception:_relationship_with_saccadic_movements_and_motion_blur" rel="nofollow noopener noreferrer"&gt;saccadic perception&lt;/a&gt;.  &lt;/p&gt;




&lt;p&gt;The serifs on a typeface cue horizontal motion similarly. &lt;/p&gt;

&lt;p&gt;They guide the horizontal “flow” of the eyes as suggested by De Lange in their study of typographical accessibility. This makes perfect sense on print because we turn the pages from left to right horizontally, and the typefaces being floored along a track motions us to move forward in the direction of flow of story—ala, line-tracking.&lt;/p&gt;

&lt;p&gt;On web however, the story is laid out vertically and the flow is scrolled downwards. Using serif fonts with horizontal marks therefore clashes with the direction of flow on a scroll. This is why typefaces that look good and feel right on web are taller and san-serif i.e. ones that present higher vertical stress than horizontal.&lt;/p&gt;

&lt;p&gt;That's all for a gyan post this week. I had fun analyzing typography closely. Did you? &lt;/p&gt;




&lt;p&gt;Written by: Marvin Danig, CEO of Bubblin Superbooks. Follow me on &lt;a href="https://bubblin.io/marvin" rel="noopener noreferrer"&gt;Bubblin&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>typography</category>
      <category>design</category>
      <category>a11y</category>
      <category>legibility</category>
    </item>
    <item>
      <title>Google Pixel 3 has a notch!</title>
      <dc:creator>Marvin Danig</dc:creator>
      <pubDate>Wed, 10 Oct 2018 00:25:17 +0000</pubDate>
      <link>https://forem.com/marvindanig/google-pixel-3-has-a-notch-56cg</link>
      <guid>https://forem.com/marvindanig/google-pixel-3-has-a-notch-56cg</guid>
      <description>&lt;p&gt;If you weren't paying attention, Google announced the &lt;a href="https://store.google.com/us/product/pixel_3"&gt;Pixel 3 XL&lt;/a&gt; today, and it has a notch! Yep, that dreaded notch that some developers loathe, but the consumers seem to be okay with.&lt;/p&gt;

&lt;p&gt;Today's announcement from Google means that as an industry we're headed towards non-rectangular viewports where one cannot assume that a CSS width declared @100% &lt;em&gt;will&lt;/em&gt; be equal to 100% available width on the viewport, especially around the notch in landscape mode.&lt;/p&gt;

&lt;p&gt;Thankfully, there's an easy standard fix for this issue as described on the following &lt;a href="https://dev.to/marvindanig/take-your-web-development-skills-a-notch-higher-2cge"&gt;blog post&lt;/a&gt;. Quite interesting to note that Google announced &lt;a href="https://developers.google.com/web/updates/2018/09/nic69#notch"&gt;CSS support&lt;/a&gt; for notched devices barely a month ago and followed it up with a notched phone themselves.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>development</category>
      <category>mobile</category>
      <category>notch</category>
    </item>
    <item>
      <title>Take your web development skills a notch higher</title>
      <dc:creator>Marvin Danig</dc:creator>
      <pubDate>Thu, 13 Sep 2018 18:50:53 +0000</pubDate>
      <link>https://forem.com/marvindanig/take-your-web-development-skills-a-notch-higher-2cge</link>
      <guid>https://forem.com/marvindanig/take-your-web-development-skills-a-notch-higher-2cge</guid>
      <description>&lt;p&gt;Raise your hands if you love the notch on iPhone X, XS, XR or XS Max! 🙋🏻‍♀️🙋‍♂️&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fb08q03geomlfmbcgzfog.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fb08q03geomlfmbcgzfog.png" title="Notched iPhones are in!" alt="notched iphone"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, not many hands went up there, but I'm sure as a developer you do love some extra "real estate" on your screen to be able to make use of. A beautiful edge-to-edge display—well, almost—makes the notch at the top of the bezel less of an eyesore for most people. &lt;/p&gt;

&lt;p&gt;In fact, it's not even an issue for most websites in portrait mode. &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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fjep9r6fa1nsc0wkoyply.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fjep9r6fa1nsc0wkoyply.png" title="Notch on Dev.to in portrait!" alt="notch on dev.to"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Landscape viewing is where the notch pokes in the eye. &lt;/p&gt;

&lt;p&gt;Take a look at dev.to for example:&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkgvldw20kmmcryhzop76.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkgvldw20kmmcryhzop76.png" title="default gutters on dev.to" alt="gutters on dev.to"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm not sure if you can see in the image clearly but the header ends abruptly both on left and right hand side, leaving behind a feeling of a bug in the layout. This is truer and worse on Youtube.com:&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9ys5giyib03mu9vkafea.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9ys5giyib03mu9vkafea.png" title="default gutters on youtube.com" alt="gutters on dev.to"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Terrible. &lt;/p&gt;

&lt;p&gt;The issue feels particularly bad on Youtube because I normally watch videos in landscape mode and after every video I get to see this glaring bug with blood red color all over it. 🤢&lt;/p&gt;

&lt;p&gt;It's important to note here that all of the websites discussed above do have their header &lt;code&gt;width&lt;/code&gt; set to 100% in their layout. So there is an understood expectation for the header to occupy full width of the screen. But that's not the case however. It's just that browsers like Safari and even &lt;a href="https://developers.google.com/web/updates/2018/09/nic69#notch" rel="noopener noreferrer"&gt;Chrome v69&lt;/a&gt; on iOS introduce these white bars by adding a little bit of extra margin to your page so that the content isn’t obscured by the notch. &lt;/p&gt;

&lt;p&gt;They call it &lt;code&gt;safe area&lt;/code&gt; margins.&lt;/p&gt;
&lt;h1&gt;
  
  
  Enter viewport-fit meta tag and CSS environment variables.
&lt;/h1&gt;

&lt;p&gt;Here's a simple fix to use all the extra space. To tell the browser to expand into the display cutout (notched) area, set the &lt;code&gt;viewport-fit&lt;/code&gt; property to &lt;code&gt;cover&lt;/code&gt; like so:&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;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;'viewport'&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;'initial-scale=1, viewport-fit=cover'&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;That should do the trick, especially for the &lt;code&gt;sticky&lt;/code&gt; header on top. If you want to use the entire screen area but at the same time avoid content going under the notch, use &lt;code&gt;css&lt;/code&gt; environment variables like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nc"&gt;.content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;safe-area-inset-left&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;padding-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;safe-area-inset-right&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Basically there are four CSS rule options to handle 
   the notch from all four sides of the iPhone. I don't 
   recommend using them though!

padding: env(safe-area-inset-top) 
         env(safe-area-inset-right) 
         env(safe-area-inset-bottom) 
         env(safe-area-inset-left);

*/&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Another approach to solving left and right padding on the body of content correctly is to simply use &lt;code&gt;width&lt;/code&gt; definitions per &lt;code&gt;@media-query&lt;/code&gt;, like so:&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="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;portrait&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="err"&gt;.shrink&lt;/span&gt; &lt;span class="err"&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;95%&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="err"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;landscape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="err"&gt;.shrink&lt;/span&gt; &lt;span class="err"&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;90%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;Shrink&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;little&lt;/span&gt; &lt;span class="err"&gt;extra&lt;/span&gt; &lt;span class="err"&gt;to&lt;/span&gt; &lt;span class="err"&gt;avoid&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;notch.&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;span class="nc"&gt;.center&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="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&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;And then in your HTML, the &lt;code&gt;main&lt;/code&gt; container element can sit with &lt;code&gt;css&lt;/code&gt; classes &lt;code&gt;shrink center&lt;/code&gt; to work across &lt;em&gt;all&lt;/em&gt; devices and &lt;em&gt;all&lt;/em&gt; viewports with just one rule definition. I prefer doing it this way to avoid using device specific hacks like &lt;code&gt;safe-area-insets&lt;/code&gt;.&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;header&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!--Sticky header with 100% width across and above the notch --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"shrink center"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Body goes here --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Full screen width under the notch --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;That's how &lt;a href="https://bubblin.io" rel="noopener noreferrer"&gt;Bubblin Superbooks&lt;/a&gt; scales from Apple Watch to the iPad to desktop all the way up to television sets. 🎩&lt;/p&gt;

&lt;p&gt;There are some other fancy solutions around the notch out there using &lt;code&gt;JavaScript&lt;/code&gt; but it's really not recommended. Overkill. Less code means better maintainability. And similarly, less CSS =&amp;gt; more scalability. &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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpqksv766pnuwd3csyb4s.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpqksv766pnuwd3csyb4s.png" title="bubblin superbooks" alt="bubblin in landscape mode"&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4wo5tvmrk9o5k5dxwtln.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4wo5tvmrk9o5k5dxwtln.png" title="superbook landscape" alt="superbook in landscape mode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all for now folks. Stay cool. ❤️&lt;/p&gt;




&lt;p&gt;Follow me on &lt;a href="https://twitter.com/marvindanig" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or on &lt;a href="https://github.com/marvindanig" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This post originally appeared on &lt;a href="https://bubblin.io/blog/notch" rel="noopener noreferrer"&gt;The Bubblin Blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>development</category>
      <category>mobile</category>
      <category>beginners</category>
    </item>
    <item>
      <title> How to set up a simple jekyll blog near your rails app.</title>
      <dc:creator>Marvin Danig</dc:creator>
      <pubDate>Tue, 04 Sep 2018 21:40:44 +0000</pubDate>
      <link>https://forem.com/marvindanig/-how-to-set-up-a-simple-jekyll-blog-near-your-rails-app-5c3o</link>
      <guid>https://forem.com/marvindanig/-how-to-set-up-a-simple-jekyll-blog-near-your-rails-app-5c3o</guid>
      <description>&lt;p&gt;So your prototype is ready to go live and you need a blog to announce your upstart to the world. &lt;/p&gt;

&lt;p&gt;Great!, but how do you do that?&lt;/p&gt;

&lt;p&gt;…¯\&lt;em&gt;(ツ)&lt;/em&gt;/¯ &lt;/p&gt;

&lt;p&gt;It's so easy to set up a blog that you wouldn't want to miss all that "domain authority" on web for your fledgling company. Miss out on the SEO juices that come along with a subdirectory like this: &lt;code&gt;/domain.com/blog&lt;/code&gt;? &lt;/p&gt;

&lt;p&gt;IMO, if you're doing a tech startup it is important to wiggle a little harder and setup your &lt;em&gt;own&lt;/em&gt; blog. Blog is how the search Gods will look at you, at minimum, instead of Medium.&lt;/p&gt;

&lt;p&gt;The following guide will help you setup a simple &lt;a href="https://jekyllrb.com/"&gt;Jekyll&lt;/a&gt; blog alongside your rails app but the process would essentially be the same no matter which stack (node, python, java or others) you're on.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This post assumes that you love &lt;em&gt;ruby_on_rails&lt;/em&gt; like I do and have an application (startup?) alive at your own &lt;code&gt;domain.com&lt;/code&gt;. And now, you need a blog at &lt;code&gt;/blog&lt;/code&gt; url of &lt;code&gt;domain.com&lt;/code&gt; to dent the world with your announcement post. &lt;/p&gt;

&lt;p&gt;Dang!, you're at the right place at the right time right now, so read on…&lt;/p&gt;

&lt;p&gt;Of course, we too made our &lt;a href="https://bubblin.io/blog/announcement"&gt;announcement&lt;/a&gt; too using the same technique last week!&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;We wanted to have a blog for &lt;a href="https://bubblin.io"&gt;Bubblin Superbooks&lt;/a&gt; to release new features on and post updates to. We are on &lt;code&gt;rails 5.2&lt;/code&gt; and wanted our blog to reside on the same &lt;em&gt;top_level_domain&lt;/em&gt; (&lt;a href="https://bubblin.io/blog"&gt;https://bubblin.io/blog&lt;/a&gt; vs. blog.bubblin.io) as the main product itself. Why? Because SEO, if you missed it earlier.&lt;/p&gt;

&lt;p&gt;There's a couple of ways of setting up a blog, and quite a few open source options (wordpress/ghost etc.) out there, but we decided on using Jekyll with &lt;em&gt;markdown&lt;/em&gt; for the sake of simplicity. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Jekyll is &lt;code&gt;rack&lt;/code&gt; based like all rails-apps generally are, and I really enjoy writing with markdown. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For the uninitiated, Jekyll is a simple blog-aware generator, so all we need to do is be able to publish it alongside our rails app online, via the &lt;code&gt;public&lt;/code&gt; directory. The web-server will take care of the rest from there. Note the blog doesn't have to be coupled with the rails app itself, it just has to sit nearby, like a sibling, and work in a way similar to how static uploads do. &lt;/p&gt;

&lt;p&gt;Let's look at the setup first. &lt;/p&gt;

&lt;h1&gt;
  
  
  Setup
&lt;/h1&gt;

&lt;p&gt;Assuming that your startup (or rails app) is going to be called &lt;code&gt;domain.com&lt;/code&gt;, in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
$ mkdir ~/projects/domain.com
$ cd ~/projects/domain.com
$ rails new domain.com          // your app may already exist. 

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

&lt;/div&gt;



&lt;p&gt;Now that we have the rails app (&lt;em&gt;~/project/domain.com/domain.com&lt;/em&gt;), let's go ahead and get our blog ready. As of writing this post jekyll requires you have at least Ruby 2.2.5 installed on your system, but for the latest instruction, check the Jekyll setup &lt;a href="https://jekyllrb.com/docs/installation/"&gt;guide&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd ~/projects/domain.com      // or cd .. if you're inside the rails app.
$ gem install bundler jekyll
$ jekyll new domain.blog
$ cd domain.blog &amp;amp;&amp;amp; bundle install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go ahead and commit your blog to its own new repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git init &amp;amp;&amp;amp; git add . -A
$ git commit -m "Setting up a jekyll blog on the side…"
$ git remote add origin git@github.com:username/domain.blog.git
$ git push -u origin master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once Jekyll finishes you'll have the blog at &lt;em&gt;~/project/domain.com/domain.blog&lt;/em&gt; and the Rails app at &lt;em&gt;~/project/domain.com/domain.com&lt;/em&gt;, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;➜ marvindanig-@bubblin in ~/projects/domain.com: $ ls

domain.blog domain.com

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

&lt;/div&gt;



&lt;h1&gt;
  
  
  Configuration
&lt;/h1&gt;

&lt;p&gt;This is what our jekyll blog looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;➜  ls ~/project/domain.com/public/domain.blog
404.html      Gemfile.lock  _posts        bin           index.md
Gemfile       _config.yml   _site         contact.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the &lt;code&gt;baseurl&lt;/code&gt; option on &lt;code&gt;_config.yml&lt;/code&gt; of your jekyll instance to point it to &lt;code&gt;/blog&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;baseurl: "/blog"            // the subpath of your site, e.g. /blog, /docs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is important so that assets load and link back properly. To ensure everything is working properly, start the Jekyll server and preview the blog on your browser. You can also apply a theme to your blog to match with your site's layout. We customized our Jekyll blog and open sourced our theme in form of a &lt;em&gt;gem&lt;/em&gt; along with a &lt;a href="https://github.com/bookiza/bubblin-jekyll"&gt;guide&lt;/a&gt; to help you dip your fingers in quickly: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bookiza/bubblin-jekyll"&gt;https://github.com/bookiza/bubblin-jekyll&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;(Simply fork it, replace logos and links and you're all set!)&lt;/p&gt;

&lt;p&gt;Since we're hosting Bubblin on &lt;a href="https://www.linode.com/?r=98af25a1733481db3f0afe644f31fd2faff8fecd"&gt;Linode&lt;/a&gt; I wanted to make sure that the &lt;code&gt;public/&lt;/code&gt; directory is committed properly. Remove 'public/' from &lt;code&gt;.gitignore&lt;/code&gt; file if that is necessary to commit the directory. What we’ll be doing next is simply add a &lt;code&gt;shared&lt;/code&gt; directory on our deployer recipe to tell rails where the requests to our blog will go. Thereon we can just build and rsync the Jekyll site to our blog directory on server. Easy peasy. &lt;/p&gt;

&lt;p&gt;We're using Capistrano for build deployments so I added the "blog/" as a &lt;code&gt;linked_directory&lt;/code&gt; on our deployer recipe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;➜ $ cd ~/project/domain.com/domain.com/config/        // In your rails/node/python app
➜ $ vi ~/project/domain.com/domain.com/config/deploy.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add &lt;code&gt;public/blog&lt;/code&gt; to the following line:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;set :linked_dirs, %w{public/blog log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Exit vim with &lt;code&gt;\wq!&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Publish
&lt;/h1&gt;

&lt;p&gt;To publish we’ll use a two line deployer script that builds jekyll and rsyncs it to the public directory of our Rails application. If you don’t have rsync installed, you could use &lt;code&gt;scp&lt;/code&gt; instead, or you’ll need to install one of these tools with your favorite package manager. Since I'm on mac, I use the &lt;a href="https://brew.sh/"&gt;Homebrew&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd ~/project/domain.com/domain.blog/ &amp;amp;&amp;amp; mkdir bin     // Create a `bin` dir here.
$ cd bin &amp;amp;&amp;amp; touch deploy                // Note there is no dotfile extension on this script
$ vi deploy

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

&lt;/div&gt;



&lt;p&gt;Add the following lines to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#! /bin/sh

jekyll build
rsync -va _site/ ../domain.com/public/domain.blog
# rsync -va _site/ deployer@domain.com:/var/www/domain.com/shared/public/blog   // Uncomment for production.


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

&lt;/div&gt;



&lt;p&gt;Exit vim with &lt;code&gt;\wq!&lt;/code&gt;. It’s a good idea to make it executable as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod +x ~/project/domain.com/domain.blog/bin/deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the root of your blog execute &lt;code&gt;$ . bin/deploy&lt;/code&gt;, and you’ll see rsync run and  put the Jekyll build inside your rails app's &lt;code&gt;public/&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Now you can work on the app and the blog independently without mixing dependencies. &lt;/p&gt;

&lt;p&gt;That's how you setup a simple jekyll blog &lt;em&gt;near&lt;/em&gt; your rails app. And all the best with your startup!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;P.S.:&lt;/strong&gt; Did you know &lt;a href="https://bubblin.io"&gt;Bubblin&lt;/a&gt; is to books, what Jekyll is to blogs?&lt;/p&gt;

&lt;p&gt;A condensed version of this post appeared on &lt;a href="https://bubblin.io/blog/set-up-jekyll-blog-quickly-alongside-your-rails-app"&gt;The Bubblin Blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>rails</category>
      <category>webdev</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
