Front-End Friday: House Brand

by Richard 2021-10-08 09:40


House brand hero image

TL;DR

CSS Grid is cool and fun.

  1. Go watch Responsive Mondrian – a demo of CSS Grid by Layout Land
  2. Find a label in your house and emulate it in HTML and CSS using CSS Grid

A CSS Grid Excercise

Let me get this out of the way: this site is Bootstrapped to hell. It's a great asset. But I started learning HTML from before there was a Bootstrap, or a Twitter for that matter. Coding boot camp taught it because it is quick to prototype. To me it made some super-ugly HTML.

I didn't like it, so I went looking for any other solution to layouts. That led me to "YouTube U" where I found CSS Grid and Jen Simmons's excellent channel, Layout Land.

Grid was fun to play with and it was not Bootstrap. You could make an impressive and fun demo in a few minutes. It wowed when I showed it as a teaching assistant at the coding boot camp.

Finding an Inspiring Lesson

Ms. Simmons teaches layout and ties it to design, giving practical examples in many of her videos. One in particular—Responsive Mondrian – a demo of CSS Grid—was very, very helpful to me. In it, she emulates a Piet Mondrian painting, which fits CSS Grid particularly well.

Tableau I, by Piet Mondriaan

Tableau I, by Piet Mondrian

Her video is well worth the view.

Bringing the Lesson Home

After watching this video I was inspired to create two projects. The first was a responsive grid a la the primary subject of the video. The second was to emulate a design I could find in my house using CSS Grid. I happened upon a label for disinfecting wipes under my sink. One of Amazon's generic brands. Check it out:

Amazon cleaning wipes house brand

Solimo disinfecting wipes—a must in the early pandemic times

I know very little about design but I do know that is a hot mess. Look at it! Serif fonts, sans-serif fonts, eight-plus font sizes, bold, italics, footnotes, a superscript, a subscript, a horizontal rule...I love it; it's perfect for some CSS Grid stretch exercise.

Getting Started: HTML

Starting off with the HTML, I created the file index.html in the root of the project folder. To house all the parts of the label I used the <main> tag as a container.

index.html

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <main>
    </main>
</body>
</html>

Next, I looked at what was on the label. You cannot see it in the image above, but there are yellow-ish vertical bars on either side of the white label. For the left bar I made a <div> and for the right an <aside>. These could both be <div> and each with a separate class, e.g. <div class="left-bar">, but this gets the job done, and avoids what was annoying me about Bootstrap: loads of divs and classes.

(Upon reflection, this whole exercise might have been me throwing a tantrum about doing things in a modern way.)

There's a yellow bar for the header and one for the footer. Those got their own tags: <header> and <footer>.

Here is my structure in HTML at this point.

index.html

<body>
    <main>
        <div></div> <!-- left bar -->
        <header></header> <!-- top yellow bar -->
        <footer></footer> <!-- bottom yellow bar -->
        <aside></aside> <!-- right bar  -->
    </main>
</body>

CSS Grid applies to the immediate child elements, so when we make a grid in the <main> tag, it applies to the immediate child elements, but not elements that are nested inside those elements. The elements <div>, <header>, <footer>, and <aside> are all subject to the Grid we will declare in <main>. Any sections that are going to contain the information that goes on the label will need to be placed on the grid at that same level. You could make these <div> elements. I used <article> elements because I have been told that is more modern or best practice or whatever. "Semantic!" That's the word. Because the <article> tags are all the same each required a different class. You could use IDs, sure, but They say that it is not good practice to style IDs. Fine, They—have it your way.

index.html

<body>
    <main>
        <div></div> <!-- left bar -->
        <header></header> <!-- top yellow bar -->
        <article class="item1"></article>
        <article class="item2"></article>
        <article class="item3"></article>
        <article class="item4"></article>
        <article class="item5"></article>
        <article class="item6"></article>
        <footer></footer> <!-- bottom yellow bar -->
        <aside></aside> <!-- right bar  -->
    </main>
</body>

(Yeah, OK, these are basically the thing I was trying to avoid.)

If you are deciding to look at this HTML file in a browser, you will see nothing. That's OK.

They say HTML is the skeleton of our document. I don't care for that analogy because a lot of bones are curvy and you layer all the stuff that makes a body around them. HTML documents are not curvy. I prefer to think of it like a bookshelf. We put the content in the tags, like you would put content in bookshelves. Here are two of those shelves to give an idea of what I did with the content of the label.

index.html

<article class="item1">
    <h1>solimo</h2>
</article>

<!-- ... -->

<article class="item6">
    <p>active ingredients:</p>
    <ul>
        <li>Loremade deinteresting<span>0.0909&#37;</span></li>
        <li>Genericyl packygin<span>0.0364&#37;</span></li>
        <li>Lorem, ipsum dolor<span>0.0545&#37;</span></li>
        <li>Flotsomin gerrynin<span>0.1212&#37;</span></li>
    </ul>
    <p>other ingredients:</p>
    <ul>
        <li>Blankyn spacil<span>99.6970&#37;</span></li>
    </ul>
    <p><sup>1</sup>includes weight of absorbent wipe</p>
</article>
.item1

This is perhaps the most simple part of the label. There is one word. There's also a horizontal rule, but I address that in the CSS.

.item6

I'm having a little fun with the language, so it doesn't match what is on the label exactly. (Last I checked "Lorem ipsum" was not an ingredient for anything.) There are <p> tags before the lists, then the ingredients lists themselves. The <span> element will allow us to keep the amount of the ingredient in the same line, but mess with the alignment. &#37; is the HTML code for "%". The only other thing is the <sup> tag, which is for "superscript".

You might note that there are a lot of places where my capitalization is inconsistent. The name brand, the <p> elements before the lists...these are all going to be capitalized in the end, and I did that using CSS. It doesn't matter if we write "Active Ingredients," or "aCtive iNgredients," or "aCTIVE INGredients".

After filling out the other parts of the HTML my document looked like this.

screenshot of the unstyled HTML

Unstyled HTML

An <h1>, an <h2>. A lot of <p> tags. Some lists. One <sub>, one <sup>. That's pretty much what was needed for content. Let's style!

CSS

Here is the directory structure I used for this project:

house-brand/
|_index.html
|_css/
  |_style.css

If you're following along, create the directory css/ and then in there, style.css. Then link to it in the HTML. Oh, and I added a title.

index.html

<head>
    <title>House-Brand</title>
    <link rel="stylesheet" href="./css/style.css">
</head>

I wanted this to be centered in the browser. Most tutorials would use a <div class="container">, but this is a simple exercise so I'm just styling the <body> tag.

css/style.css

body {
    margin: 0 auto;
    width: 75%;
}

That margin: 0 auto; is something I use frequently. The top and bottom of the element have no margin at all and the left and right are evenly distributed using the auto value. The <body> has a width of 75% of whatever you would view it on. I am not going for responsive or mobile here; this is best viewed on a monitor.

The Grid

If you checked out the Layout Land tutorial or perhaps the W3 Schools Grid Layout Module you might know there are a few ways to make a grid. I'm opting for the shorthand version. As I mentioned, <main> is the grid container.

css/style.css

main {
    display: grid;
    grid: 80px repeat(3, 125px) 250px 80px / repeat(5, 1fr);
    gap: 1rem;
}

Make the grid with display: grid;. Then establish how many rows and columns and of what size with the grid property. Breaking down those values:

  • 80px is the first row; <header> lives here
  • repeat(3, 125px) is three rows of 125px for .item1, .item2, and .item3
  • 250px is one row for .item4, .item5, and .item6
  • 80px for the <footer>
  • / divides the rows from columns
  • repeat(5, 1fr) creates five columns, each one flex unit, which for whatever reason is "fr"; in my head that is "one fraction, repeated five times"

Then I put a gap around the grid items of 1rem just so everything isn't smooshed.

Here's another view of the label showing the rows and where each element is going to live. And because I don't have a good, flat version of the label, you'll have to imagine that it is divided into five equal columns.

Solimo can overlayed with rows describing where the tags will go

Placement of HTML tags on the Grid rows—yeah, I know it's not to scale

To put content where it should go I am using the grid-area property in each of the child elements of <main>. Here is the CSS for the <header>, which spans one row and multiple columns:

css/style.css

header {
    grid-area: 1 / 2 / 2 / 5;
    height: 100%;
    background-color: #FFF75E;
}

Here is how I read grid-area in my head:

  • Start at row 1
  • Start at column 2 (remember there are side bars that are not visible in the image of the can...<div> and <aside>)
  • End at row grid line 2
  • End at column grid line 5

Here's <div> for the side bar on the left:

css/style.css

div {
    grid-area: 1 / 1 / 7 / 2;
    background-color: antiquewhite;
}

"Start at row 1, column 1, end at row 7, column 2."

After setting up my grid-area for the sections of my grid, I found it helpful to use the border property on my <article> tags to see what I was working with.

Note: the images below include styling for the content. If you are working through this example on your own, don't fret if your fonts look different.

css/style.css

/* Testing and illustrating grid areas--to be removed */
article {
    border: black solid 2px;
}
screen capture of the coded version of the Solima label, modified to label grid areas

The Grid layout showing element tags/classes; a border has been applied to the article elements as a visual aid

Here is another view, this time removing the borders and instead utilizing the "Overlay Grid" selection in Firefox's Web Developer Tools.

screen capture of the coded version of the Solima label with Mozilla Firefox Web Developer Tools Overlay Grid selected

The Grid layout showing element tags/classes; note the five flex unit columns and the 1rem gap between grid areas

Note that grid lines can be expressed as negative numbers. I can better read something like <div> when I express the grid area like this:

css/style.css

div {
    grid-area: 1 / 1 / -1 / 2;
    background-color: antiquewhite;
}

Now when I read that in my head it says, "Start at the top row, start at the first column, end at the bottom of the last row, and end at the second column grid line."

The Rest of the Styling

I added color to the side bars, header, and footer. The text is...well, there's more variance in there than an email from my parents with the subject line "FWD: fwd: FWD: FW: FWD: fwd: [...]". Best to concentrate on the most common things first.

Most of the fonts are sans-serif. I used a sans-serif stack for the value of the font-family attribute and stuck that in main.

css/style.css

main {
    display: grid;
    grid: 80px repeat(3, 125px) 250px 80px / repeat(5, 1fr);
    gap: 1rem;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

Earlier in the HTML section I had mentioned that my capitalization was all over the place for the content and that it would be dealt with in the CSS. Pretty much anything in ALL CAPS was treated with text-transform: uppercase;.

There are two lists in .item6. They are unstyled and each <li> contains a <span> that is on the right of the paragraph.

css/style.css

ul {
    list-style-type: none;
    padding: 0;
}

span {
    float: right;
}

Next I hit the obvious whitespace on the left of the label. Each <article> element that occupies the second column got padding and I messed with the amounts and units until I settled on padding: 5rem;. This makes a great case for using a CSS preprocessor—a single variable to put in the padding would be preferrable to modifying the values in four different code blocks—but that is for another post.

The horizontal rule under the brand name was handled by the pseudo element ::after.

css/style.css

/* Pseudo-element to draw a horizontal line */
.item1::after {
    content: "";
    display: block;
    width: 100%;
    height: 5px;
    background-color: black;
}

After that the efforts turned to parts of content that had very different treatments within the same class. .item4 and .item5 required quite a bit of experimentation, and that is where a lot of learning occurred. I'm going to zoom into .item4 to explain what I did.

css/style.css

.item4 {
    padding-left: 5rem;
    text-transform: uppercase;
    font-weight: bolder;
}

.item4 p:nth-child(2) {
    margin-bottom: 4px;
}

.warning {
    font-size: 25px;
    margin: 5px 0;
    letter-spacing: -2px;
    font-weight: 700;
}

.item4 p:nth-child(4) {
    margin-top: 5px;
    font-size: 10px;

}

So this code establishes where the content will be from the left border with padding-left: 5rem;, the capitalization of all the text with text-transform: uppercase;, and everything in this particular <article> is a little bit bold, so I used font-weight: bolder;. To treat different paragraphs specifically I used the pseudo-class :nth-child(). I also assigned a class .warning which does the same thing as :nth-child() in a different way. (Stretch exercise, remember?) You could use .item4 p:nth-child(3) instead of .warning. The word "CAUTION" on the label is a bit bigger than the other paragraphs (font-size), has some vertical space between its neighbors (margin), is a little smooshed together (letter-spacing), and is a little bolder than the others (font-weight).

.item5 got a similar treatment to .item4.

For .item6 the font size was the same, but the <p> items were uppercase while the items in the list were not. Font size was determined in the code block of the class, then the uppercase was handled by a separate code block: .item6 p { text-transform: uppercase }

Wrapping It Up

After looking back at this exercise I can see a lot of sloppy code, but that is sort of the point—this exercise was to play with CSS using Grid and a minimal amount of classes in the HTML. Aside from each <article> getting a class there is only .warning, and that could be changed to not use a class as mentioned above.

I had lunch with a friend the other day and they lamented the fact that there seemed to be so few candidates that could emulate a layout handed to them during an interview. I was reminded of this exercise. If you've got anything around your household that could be emulated in a grid, I highly encourage you to create your own emulation.


The project lives on Github pages and you can find the repository here.

You may notice that there is some JavaScript and a previously-unmentioned <div> in the project before <main>. That was added to create a button that will toggle an overlayed picture of the original label.

Go Back

Leave a comment

Comments 0