javascript – Device-specific page design with gatsby


I’ve been coding for a couple weeks now and have nearly finished the first version of a gatsby site for a landing page. My aim is to make the addition of new pages to the website as fast as possible by setting up a system where this can be done quickly, but still work across mobile or desktop. I’d really appreciate some feedback as to whether my code follows best practices and if there are any major rookie errors.

The structure of the website is built around a main sitewrapper, with all content inside the central column:

    .siteWrapper {
        display: grid;
        position: relative;
        grid-template-columns: 5vw 90vw 5vw;
        grid-auto-rows: auto auto auto auto auto auto;
        color: var(--primary-text);
        font-family: var(--font);
        border-style: var(--border-style);
        border-color: var(--border-color);
    }

When the site loads in it uses a snippet of code I borrowed to get the viewport width and height, then compare them such that if the viewport is taller than it is wide, it sets the page to mobile and vice versa, as it returns a component tag, i decided to build the mobile and desktop versions of the page separately, and have them used through this. This piece of code is loaded in using loadable-component as when using netlify it couldn’t find the viewport when server-side-rendered so crashed. This means that the main page file only contains this:

import React from "react";
import loadable from "@loadable/component";

const PageLayout = loadable(() => import("./landing-page.js"))

const IndexPage = () => (
  <PageLayout/>
)

export default IndexPage

All text in the site is styled based on a series of classes held in the layout.css file, with different styling for mobile and desktop (with larger text on mobile for visibility etc.):

.mobileTextHeading {
  color: var(--primary-text);
  font-family: var(--font);
  font-weight: var(--mobile-heading-weight);
  text-rendering: optimizeLegibility;
  font-size: var(--mobile-heading);
  line-height: 1.1;
}
.mobileTextBody {
  color: var(--primary-text);
  font-family: var(--font);
  font-weight: 400;
  text-rendering: optimizeLegibility;
  font-size: var(--mobile-body);
  line-height: 1.1;
}
.desktopTextHeading {
  color: var(--primary-text);
  font-family: var(--font);
  font-weight: var(--desktop-heading-weight);
  text-rendering: optimizeLegibility;
  font-size: var(--desktop-heading);
  line-height: 1.1;
}
.desktopTextBody {
  color: var(--primary-text);
  font-family: var(--font);
  font-weight: 400;
  text-rendering: optimizeLegibility;
  font-size: var(--desktop-body);
  line-height: 1.1;
}

Inside the central column of the sitewrapper is a series of predefined rows which is where i place the components, i had some issues with making these autosize around the components so i used a set of variables for each one which gives them their height, i gave 5 to each one as then i can include the heights given to each part of the component within it, which can be added to give the row height. Here’s an example of the first variable set:

:root {
    --row1-h1: 0vh;
    --row1-h2: 0vh;
    --row1-h3: 0vh;
    --row1-h4: 0vh;
    --row1-h5: 0vh;
    --row1: calc(var(--row1-h1) + var(--row1-h2) + var(--row1-h3) + var(--row1-h4) + var(--row1-h5));

To use these variables i pass a prop with the name of the row used, and the heights of each part of the component (title row, body text row etc.) which are then used to set the properties of the main variable for that row. The props are passed as such:

<TripleColumn 
        headings="desktopTextHeading"
        bodytext="desktopTextBody"
        triplecolumn1height="30vh"
        triplecolumn1row="--row2-h1"
        triplecolumn2height="40vh"
        triplecolumn2row="--row2-h2"
        imgtopleft={speed} 
        topleft="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi tincidunt tincidunt arcu a ultricies. Maecenas laoreet placerat mauris vel aliquam. "
        toplefttitle="Lorem ipsum dolor sit amet"
        imgtopleftheight="50vw"
        imgtopmid={accuracy}
        imgtopmidheight="50vw"
        topmid="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi tincidunt tincidunt arcu a ultricies. Maecenas laoreet placerat mauris vel aliquam. "
        topmidtitle="Lorem ipsum dolor sit amet"
        topright="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi tincidunt tincidunt arcu a ultricies. Maecenas laoreet placerat mauris vel aliquam. "
        toprighttitle="Lorem ipsum dolor sit amet"
        imgtopright={humanerror}
        imgtoprightheight="50vw"
      />

They are used in the component like so:

function TripleColumn(props) {
    let heightVar1 = props.triplecolumn1height;
    let heightVar2 = props.triplecolumn2height;
    let tripleColumnRowNo1 = props.triplecolumn1row;
    let tripleColumnRowNo2 = props.triplecolumn2row;
    document.documentElement.style.setProperty(String(tripleColumnRowNo1), heightVar1);
    document.documentElement.style.setProperty(String(tripleColumnRowNo2), heightVar2);
    document.documentElement.style.setProperty("--tripleColumnH1", heightVar1);
    document.documentElement.style.setProperty("--tripleColumntext", heightVar2);
    return(
        <div class="tripleColumn">
            <div class='leftTitle'>
                <img src={props.imgtopleft} alt={props.imgtopleftalt} height={props.imgtopleftheight}></img>
                <p class={props.headings}>{props.toplefttitle}</p>
            </div>
            <div class='midTitle'>
                <img src={props.imgtopmid} alt={props.imgtopmidalt} height={props.imgtopmidheight}></img>
                <p class={props.headings}>{props.topmidtitle}</p>
            </div>
            <div class='rightTitle'>
                <img src={props.imgtopright} alt={props.imgtoprightalt} height={props.imgtoprightheight}></img>
                <p class={props.headings}>{props.toprighttitle}</p>
            </div>
            <div class='leftText'>
                <p class={props.bodytext}>{props.topleft}</p>  
            </div>
            <div class='midText'>
                <p class={props.bodytext}>{props.topmid}</p>
            </div>
            <div class='rightText'>
                <p class={props.bodytext}>{props.topright}</p>  
            </div>
            
        </div>
    );
    
}

This is what i saw to be the simplest way i could do it, without rebuilding my code into classes or something similar, is this a reasonable way to do the job or are there other methods of sizing the rows that would make the code run faster/be neater? I’ve tried autosizing for the main rows but for some reason haven’t managed to make that work.