<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Steven Salka</title>
    <description>The latest articles on DEV Community by Steven Salka (@ssalka).</description>
    <link>https://dev.to/ssalka</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%2F18402%2F4843a3d9-260b-4797-a5d2-58e17ebc02cf.jpg</url>
      <title>DEV Community: Steven Salka</title>
      <link>https://dev.to/ssalka</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ssalka"/>
    <language>en</language>
    <item>
      <title>Pixels are Tech Debt</title>
      <dc:creator>Steven Salka</dc:creator>
      <pubDate>Fri, 02 Feb 2018 19:17:40 +0000</pubDate>
      <link>https://dev.to/ssalka/pixels-are-tech-debt-2570</link>
      <guid>https://dev.to/ssalka/pixels-are-tech-debt-2570</guid>
      <description>&lt;p&gt;(This article originally appeared on &lt;a href="https://medium.com/podible-engineering/pixels-are-tech-debt-ff4ff4fdeb4c" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;If you're a software engineer, then like me, you spend a lot of your time reading and writing code. The more code you read, the more patterns you begin to observe. The more code you write, the more you understand why one pattern may be chosen over another. But some patterns are better than others, and some are downright terrible.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Simple Design Taken Entirely the Wrong Way
&lt;/h3&gt;

&lt;p&gt;Imagine you are given designs for a new website layout, and need to come up with a &lt;code&gt;PageLayout&lt;/code&gt; component that implements the design. According to the specs, the finished page should look something like this on desktop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+--------------------------------------------------------+
| Logo                                          Settings |
+-------------------------------+------------------------+
|                               |       Page Title       |
|                               +---------+--------------+
|            Main               |   Nav   |     Page     |
|            Page               |  Links  |  Description |
|           Content             |   ...   |     ...      |
|              .                +---------+--------------+
|              .                |                        |
|              .                |         (empty)        |
|              .                |                        |
|                               +---------+              |
|                               |  Share  |              |
|                               | Buttons |              |
+-------------------------------+---------+--------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, a bit of an odd layout, but at first glance it looks pretty easy to implement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Put a full-width &lt;code&gt;div&lt;/code&gt; going across the top of the page - float the logo left, user settings right&lt;/li&gt;
&lt;li&gt;Set up 2 main columns - one on the left (for scrollable page content), and one on the right (for...everything else)&lt;/li&gt;
&lt;li&gt;Hmm... the site title, links, and description are arranged in the same way the overall page is! Let's just reuse our &lt;code&gt;PageLayout&lt;/code&gt; component - we'll keep it DRY!!!

&lt;ul&gt;
&lt;li&gt;Edge case: We just need to be sure we never pass a &lt;code&gt;PageLayout&lt;/code&gt; instance as the page description, or the component render may go into infinite recursion and break the site, likely making it difficult for the user to close the window.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Phew, glad that's over with... what about these share buttons? With nothing else around them? Let's just add &lt;code&gt;position: absolute;&lt;/code&gt; and call it a day.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Yeesh... not as simple as it looked initially. But, hours were spent on it, so time to check the code into version control!&lt;/p&gt;

&lt;h3&gt;
  
  
  A Pull Request that Shouldn't Have Been Approved
&lt;/h3&gt;

&lt;p&gt;Let's quicky go over what's been done so far:&lt;/p&gt;

&lt;p&gt;Does the above approach produce the desired layout? Yes, if we make certain assumptions about how the CSS is organized (hint: generally not safe to do).&lt;/p&gt;

&lt;p&gt;Is there any ambiguity as to where the child elements will render? No, except for maybe the share buttons, but we can just have consumers override the styles if necessary.&lt;/p&gt;

&lt;p&gt;Does the component demonstrate any useful abstractions? Well, the outer layout was reused as part of the right column, so it saved the developer from writing a few extra &lt;code&gt;div&lt;/code&gt; elements...&lt;/p&gt;

&lt;p&gt;Ok, overall could be better, but it exhibits the &lt;a href="https://en.wikipedia.org/wiki/Necessity_and_sufficiency" rel="noopener noreferrer"&gt;necessary and sufficient conditions&lt;/a&gt; for the given design - which, if you ask a logician, is all it takes for something to be considered acceptable or correct.&lt;/p&gt;

&lt;p&gt;So, what's the problem?&lt;/p&gt;

&lt;h3&gt;
  
  
  A Sudden Shift in Perspective Changes Everything
&lt;/h3&gt;

&lt;p&gt;Once the new page hits production, everyone loves it. The marketing team is seeing great numbers following your deploy, and initial readings from various SaaS analytics platforms indicate that users are receptive to the redesign and are becoming more engaged.&lt;/p&gt;

&lt;p&gt;Given all this success, the design team decides it's time to take it to the next level. What does the next level look like? Pretty much the same, but now also on mobile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+-----------------------------------------+
| Logo          Page Title       Settings |
+-----------------------------------------+
|                                         |
|                                         |
|                                         |
|                                         |
|                                         |
|                                         |
|                                         |
|                  Main                   |
|                  Page               +---+
|                 Content             | S |
|                    .                | h |
|                    .                | a |
|                    .                | r |
|                    .                | e |
|                                     +---+
|                                         |
|                                         |
|                                         |
+-----------------------------------------+
|                                         |
|             Page Description            |
|                                         |
+-----------------------------------------+
|             N a v   L i n k s           |
+-----------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, looks really clean... but &lt;strong&gt;nothing&lt;/strong&gt; like the original design - the nav moved to the footer, the share buttons are in a totally different place, the columns are gone!! How am I supposed to translate what I just did into &lt;em&gt;that&lt;/em&gt;? 😱&lt;/p&gt;

&lt;p&gt;From here, I see pretty much 3 potential paths forward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add a bunch of conditional logic to reposition elements&lt;/li&gt;
&lt;li&gt;Have 2 separate implementations - one for desktop, one for mobile&lt;/li&gt;
&lt;li&gt;Redesign to better accommodate both layouts&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Option 3 sounds like a ton of work... let's get back to that one later. &lt;/p&gt;

&lt;p&gt;How about Option 1? To rearrange the desktop layout into the second would likely spell disaster, and possibly even certain death for your new favorite component.&lt;/p&gt;

&lt;p&gt;A ton of CSS rules and class names would have to be adjusted, covering pretty much every child element on the page (except for perhaps the header row containing the logo and settings menu). Looks like we could keep the &lt;code&gt;position: absolute&lt;/code&gt; for the share buttons, but that won't count for much.&lt;/p&gt;

&lt;p&gt;Using a CSS framework like Bootstrap to implement your layout? The entire point of such things is to make weird styling rules like these unnecessary, so even then it would just not feel right to get away by only mangling the existing layout.&lt;/p&gt;

&lt;p&gt;So Option 1 is out - what about Option 2? Sure, that will be easier initially, but in the long run, no one is going to want to support two completely separate implementations of the same thing. Granted, this does happen all the time in the real world, and is often a good choice for enterprise-scale teams. Still, the whole team at Podible fits into a single room at our NYC WeWork office, so naturally, we prefer to avoid such scenarios when possible.&lt;/p&gt;

&lt;p&gt;Which brings us back to Option 3.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxtymqcirbyiz3riq652.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxtymqcirbyiz3riq652.png" alt="XKCD: How Standards Proliferate" width="500" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  A Second Look at an Old Problem
&lt;/h3&gt;

&lt;p&gt;Let's revisit the two layouts - both desktop and mobile pages have a box-like structure, but the contents seem to be in totally different places depending on the type of viewing device. What are some possible ways we could redo the &lt;code&gt;PageLayout&lt;/code&gt; component to suit both arrangements?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separate 3rd-party template - less up-front work, but what happens when you need to make an adjustment that is hidden deep inside the template? OSS contributions are always valued, but if the project is not well-maintained, you could be led down a deep rabbit hole.&lt;/li&gt;
&lt;li&gt;Bootstrap - Responsive, but still would require ample help from JS&lt;/li&gt;
&lt;li&gt;Flexbox - Getting warmer, but would result in a bunch of extra div elements that act only as containers for the actual content&lt;/li&gt;
&lt;li&gt;CSS Grid - there seems to be a lot of talk about CSS grid nowadays. Let's see what the hype is all about!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before diving in and coding up the thing, it will serve us well to first look at a reduced example, to see how a simple layout can be implemented with CSS grid. One of my favorite ways is with &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Grid_Template_Areas" rel="noopener noreferrer"&gt;&lt;code&gt;grid-template-areas&lt;/code&gt;&lt;/a&gt; and &lt;code&gt;grid-area&lt;/code&gt; - these CSS rules allow you to create pretty wacky layouts with relative ease:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.wacky-grid&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="na"&gt;grid-template-areas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="s2"&gt;".    .      area-1"&lt;/span&gt;
    &lt;span class="s2"&gt;".    area-2 .     "&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.top-right&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;area-1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.bottom-center&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;area-2&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;So the &lt;code&gt;.wacky-grid&lt;/code&gt; container will become a 2x3 grid with two named grid areas &lt;code&gt;area-1&lt;/code&gt; and &lt;code&gt;area-2&lt;/code&gt;. A &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/grid-area" rel="noopener noreferrer"&gt;grid area&lt;/a&gt; is a rectangular region of cells that can be specified either by name or with row &amp;amp; column start-/end-points.&lt;/p&gt;

&lt;p&gt;A key concept of CSS grid is that &lt;em&gt;you can place its contents basically wherever you want&lt;/em&gt;. Under a &lt;code&gt;.wacky-grid&lt;/code&gt; element, children with the &lt;code&gt;top-right&lt;/code&gt; class name will be placed in the &lt;code&gt;area-1&lt;/code&gt; grid area, and children with the &lt;code&gt;bottom-center&lt;/code&gt; class name will be placed in the &lt;code&gt;area-2&lt;/code&gt; grid area. Cells marked with a &lt;code&gt;.&lt;/code&gt; will stay empty. As for the whitespace, I just added it for readability - the rule could be equivalently written as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;grid-template-areas: ". . area-1" ". area-2 .";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;...but that makes it a lot less clear what the end result will look like. 😉&lt;/p&gt;

&lt;p&gt;An implementation of &lt;code&gt;WackyGrid&lt;/code&gt; might look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;WackyGrid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"wacky-grid"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"top-right"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      I'm up in the corner!
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bottom-center"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      I'm down in the middle!
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look ma, no container &lt;code&gt;div&lt;/code&gt;s! 😁 Each child gets placed in the appropriate cell. Bonus: if you have additional children without any grid-specific CSS rules, they will get &lt;a href="https://www.sitepoint.com/a-step-by-step-guide-to-the-auto-placement-algorithm-in-css-grid/" rel="noopener noreferrer"&gt;automatically placed&lt;/a&gt; in the leftover cells.&lt;/p&gt;

&lt;p&gt;Note that grid cells can't be styled directly - only actual HTML elements can. So, if you have an empty cell you want colored black, you'll still need a div to put there.&lt;/p&gt;

&lt;p&gt;Ok, now it's time to get down to business...&lt;/p&gt;




&lt;h3&gt;
  
  
  Branching Layouts With Ease
&lt;/h3&gt;

&lt;p&gt;If CSS grids can teach you anything, it's that you can likely stop worrying so much about the HTML structure of a document, and start giving more consideration as to how the more critical pieces of data can be arranged in an intelligent way. &lt;em&gt;You don't need to add a wrapper element every time you want to have a row inside a column.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;⚠️ &lt;strong&gt;DISCLAIMER&lt;/strong&gt; ⚠️&lt;br&gt;
Before you go back to your team and say, "this article said we should use CSS grid for everything!!!", take a step back and think about when you would prefer CSS grid over another tool such as a flexbox or a 3rd-party library/framework. I find that this image sums things up fairly well:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68yaa6b3bcdkkapd2pbz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68yaa6b3bcdkkapd2pbz.png" alt="Flexbox vs Grid" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With that PSA aside, let's specify a grid for the initial layout:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PageLayout.scss&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.page-layout&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="na"&gt;grid-template-areas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="s2"&gt;"header  header  header"&lt;/span&gt;
    &lt;span class="s2"&gt;"main    title   title"&lt;/span&gt;
    &lt;span class="s2"&gt;"main    nav     description"&lt;/span&gt;
    &lt;span class="s2"&gt;"main    share   ."&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;Nice! Super simple. But how do we differentiate desktop from mobile layouts? The &lt;code&gt;grid-tempate-areas&lt;/code&gt; rule is perfect for describing such subtleties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.page-layout&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;span class="nc"&gt;.page-layout-desktop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;grid-template-areas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="s2"&gt;"header  header  header"&lt;/span&gt;
    &lt;span class="s2"&gt;"main    title   title"&lt;/span&gt;
    &lt;span class="s2"&gt;"main    nav     description"&lt;/span&gt;
    &lt;span class="s2"&gt;"main    share   ."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.page-layout-mobile&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;grid-template-areas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="s2"&gt;"header"&lt;/span&gt;
    &lt;span class="s2"&gt;"main"&lt;/span&gt;
    &lt;span class="s2"&gt;"description"&lt;/span&gt;
    &lt;span class="s2"&gt;"nav"&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;Alright, this is starting to make sense. Still, there are some fuzzy bits - we can see very clearly that the grid area names don't match up perfectly. In particular, the &lt;code&gt;share&lt;/code&gt; grid area is missing from the mobile layout!&lt;/p&gt;

&lt;p&gt;(If it weren't for the share buttons, I might say it'd be easier to just use a flexbox on mobile. For the sake of the blog post, though, let's stick to the fun new stuff 🙃)&lt;/p&gt;

&lt;p&gt;We can address these ambiguities by mapping our elements and class names to grid areas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="c1"&gt;// applies regardless of device type&lt;/span&gt;
&lt;span class="nc"&gt;.page-layout&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.logo&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.user-settings&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;justify-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.user-settings&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;justify-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nt"&gt;nav&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.description&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;description&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="c1"&gt;// desktop-specific placement&lt;/span&gt;
&lt;span class="nc"&gt;.page-layout-desktop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.page-title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.share-buttons&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;share&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;end&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="c1"&gt;// mobile-specific placement&lt;/span&gt;
&lt;span class="nc"&gt;.page-layout-mobile&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.page-title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="na"&gt;justify-self&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;span class="nc"&gt;.share-buttons&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;align-self&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="na"&gt;justify-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;right&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;This part is a bit more verbose - and there are definitely &lt;a href="https://gridbyexample.com/examples/" rel="noopener noreferrer"&gt;other ways of placing child elements&lt;/a&gt; - but this gives me a pretty good idea of where each element will appear on the page. But there's one last piece that will drastically affect how the grid appears in its final form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.page-layout-desktop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;grid-template-rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt; &lt;span class="m"&gt;25vh&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="na"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5fr&lt;/span&gt; &lt;span class="m"&gt;2fr&lt;/span&gt; &lt;span class="m"&gt;3fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.page-layout-mobile&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;grid-template-rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt; &lt;span class="m"&gt;2fr&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// not necessary to specify columns, since there's only one&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All it needed was some good ol' row &amp;amp; column sizing - without these rules, the 3 desktop rows/columns would all render with the same height/width, and the mobile main area would only take up 1/4 of the screen.&lt;/p&gt;

&lt;p&gt;If you’re wondering about this &lt;a href="https://css-tricks.com/introduction-fr-css-unit/" rel="noopener noreferrer"&gt;mysterious &lt;code&gt;fr&lt;/code&gt; unit&lt;/a&gt;, it’s short for &lt;em&gt;fraction&lt;/em&gt;, and is specific to CSS grid. Although you can implement your grid layout using only traditional units like &lt;code&gt;%&lt;/code&gt;, &lt;code&gt;em&lt;/code&gt; or &lt;code&gt;vh&lt;/code&gt;/&lt;code&gt;vw&lt;/code&gt;, I'd say it's probably the most useful unit for CSS grids, as it helps to eliminate some unnecessary calculations, e.g. &lt;code&gt;repeat(4, 1fr)&lt;/code&gt; vs &lt;code&gt;repeat(4, 25%)&lt;/code&gt;. Still, it’s an arbitrary choice - use &lt;a href="https://blog.alexdevero.com/css-units-ultimate-guide/" rel="noopener noreferrer"&gt;whichever units make the most sense&lt;/a&gt; for your use case (but &lt;a href="https://engageinteractive.co.uk/blog/em-vs-rem-vs-px" rel="noopener noreferrer"&gt;beware of &lt;code&gt;px&lt;/code&gt;!&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Finally, we'll implement the &lt;code&gt;PageLayout&lt;/code&gt; component by simply listing the page contents in a sensible, layout-independent order (child props omitted for brevity):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PageLayout.jsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PageLayout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mobile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`page-layout page-layout-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Logo&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NavLinks&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PageTitle&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PageDescription&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ShareButtons&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserSettings&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, our stylesheet will take all the child elements and place them into the corresponding grid areas. There, that wasn't so hard! 😄&lt;/p&gt;

&lt;h3&gt;
  
  
  Ok, but why?
&lt;/h3&gt;

&lt;p&gt;Now is about the time where you might find yourself saying, "this seems neat, but can I do anything &lt;em&gt;useful&lt;/em&gt; with this besides moving elements into strange places?"&lt;/p&gt;

&lt;p&gt;You sure can.&lt;/p&gt;

&lt;p&gt;At Podible, we believe in always using the right tool for job, and CSS grids efficiently solve a number of problems that are only partially addressed by most 3rd-party tools. And the more we experiment with grid layouts, the more areas it seems they can prove useful. Take our latest addition for example - the embeddable player:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr4cuwgc7hc4dj5pep9i5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr4cuwgc7hc4dj5pep9i5.png" alt="Embeddable Player Preview" width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://play.podible.co/embeddable-player/episode/4482314" rel="noopener noreferrer"&gt;(interactive version)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right now it only makes minor adjustments according to its width, but the setup is such that we'll be able to easily add new layouts to this component in the future.&lt;/p&gt;

&lt;p&gt;That's all for now - let me know how you plan to use CSS grid next in the comments below. Thanks for reading!&lt;/p&gt;




&lt;p&gt;Want to join in on the action? &lt;a href="https://angel.co/podible/jobs/318994-senior-full-stack-software-engineer" rel="noopener noreferrer"&gt;Podible is hiring a full-stack engineer&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
