CSS Layout & Responsive Layout

About this guide

Hi, welcome to our CSS Layout & Responsive Layout guide.

If you are following our guides so far, by now you might be coming across a handful of fundamental issues regarding layout. Basic HTML and CSS is great if you want a simple site that presents one thing after the other, but how do you create something with more of a layout or landscape? And how does that layout change depending on what device you're on (big screen? laptop? tablet? mobile?) Anyway, if you are having a lot of issues with CSS now, don't worry… this guide digs into more details about the weirdness and intricacies of CSS.

Note that learning CSS layout and positioning is not intuitive and requires study, practice, and trial and error. So be patient, open up your web inspector, and have fun!

Note: our weekly guides aim to provide a general landscape ... an overall survey of what’s most essential about the technology at hand and the basics of how to use it. From a technical or skill perspective, our guides are not exhaustive or thorough because there are already many other resources on the internet that are just that. We encourage you to check them out -- we’ve linked some.

Part 0. Material

wood showing its undulating grain

Every material has a grain.

Take wood for example. Wood grain generally means which orientation the wood fibers go. One of the most fundamental sayings of woodworking is to cut wood β€œwith the grain” which helps improve the strength of whatever you’re creating.

In other words, it’s good to first understand your material so you can work with it, not against it. You can best collaborate with your material if you understand its inherent tendencies.

The idea that the web has a unique grain comes from Frank Chimero, in his piece The Web’s Grain from 2015.

I believe every material has a grain, including the web. But this assumption flies in the face of our expectations for technology. Too often, the internet is cast as a wide-open, infinitely malleable material.
β€” Frank Chimero

So what is the grain of the web?

Part 1. Fluidity

water moving quickly around rocks in a stream

The web was first created as a way to share documents with anyone. Like we mentioned, many of the first people using the web to share documents were academics, or professors. You’ll see many of their sites are mostly text-based, with an image or two here and there.

Because the web was designed to present content in the form of documents, we believe the web’s grain is most easily visible the way text moves when you make the browser window a different size.

screenshot of website with lots of text in landscape mode and the text fills the screen and is wide and horizontal screenshot of website with lots of text in portrait mode and the text fills the screen but is taller than landscape mode

image of glass bowl full of water where the water appears very horizontal image of a tall pint glass full of water where the water appears very vertical

Try opening these three webpages and resizing them by making them wide and narrow, and seeing how the content is affected:

Text is inherently responsive. It goes with the flow. That's why so many old websites that are mostly text are surprisingly responsive by default.

But learning from the above examples, besides text, we can format other media so it goes with the flow, too. And maybe in general we should design how we read … left to right, top to bottom...

content is like water, and this image shows water inside a teapot, a glass, a computer, a phone

More broadly, responsive web design is a specific approach that focuses on websites rendering well on a variety of different devices β€” from mobile to tablet to desktop. A variety of techniques are employed to do this, including media queries which we touch on later in this guide.

various devices from smal to large with numerical breakpoints separating them

various computers at best buy present the same website that says hahahaha

Generally speaking, it’s not good good practice to design a rigid system with specific breakpoints for every device. Instead, exercise flow and come to terms with the difference of screens sizes and preferences are radically different form person to person, era to era.

Responsive design is a fascinating field, and experiments like responsive logos show that it happens at even with the smallest details. Being able to present the essence of a thing even at a small scale could be seen as a type literacy.

Part 2. Layout

Brief history of layout in CSS

Today in 2020, there are many ways you can lay items across your pages using CSS.

But layout hasn't always been easy. In the old days (90s and early 2000s), using <table> was one of the best strategies at the time to do layout. But a lot has changed since then, and we would recommend not using <table> unless you're displaying tabular data, like a spreadsheet.

Check out this site about web design history for more context.

Thankfully today, there are new CSS layout methods β€” like Flexbox (since 2013) and CSS Grid (since 2017), that make things much easier.

But it’s important to understand the other properties and methods as a basis since you’ll likely use a combination of techniques to attain your desired result...

Inline versus block elements

Just a little review from last guide...

By default, each element (or β€œbox”) in HTML is either an inline or block element.

Inline elements β€œgo with the flow.” If you put a lot of inline elements together, you’ll notice them flow left to right like text.

Some classic inline elements:

In this example, we started with a bunch of <span>, a classic inline element. We colored them all different colors so we can see them!

How would I define pebble? It’s a bit tricky, but if I were to start by the way of description, I should say that pebble is something somewhere between rock and stone. The obvious defect of my definition is that I can’t stop there: I have to continue defining stones and rocks all the way back to the flood and perhaps even further than that

View in new tab (try opening this and resizing it to watch the lines move!)

<span class="one">How would I define pebble?</span>
<span class="two">It’s a bit tricky,</span>
<span class="three">but if I were to start by the way of description,</span>
<span class="four">I should say that pebble is something somewhere between rock and stone.</span>
<span class="five">The obvious defect of my definition is that I can’t stop there:</span>
<span class="six">I have to continue defining stones and rocks all the way back to the flood</span>
<span class="seven">and perhaps even further than that</span>
.one { background: lime; }
.two { background: yellow; }
.three { background: cyan; }
.four { background: pink; }
.five { background: goldenrod; }
.six { background: coral; }
.seven { background: cornflowerblue; }
.eight { background: silver; }

Block elements "stack one on top of another” … like blocks. If you put a lot of blocks together, you’ll make a very tall page.

Some classic block elements:

In this example, we added one line of CSS that makes the <span> not display: inline but display: block instead. (If you want to change an element from block to inline or vice-versa, you can just override the default style with CSS.)

Now that the <span> are blocks, notice how they now go one on top of each other ... like stacked blocks.

How would I define pebble? It’s a bit tricky, but if I were to start by the way of description, I should say that pebble is something somewhere between rock and stone. The obvious defect of my definition is that I can’t stop there: I have to continue defining stones and rocks all the way back to the flood and perhaps even further than that

View in new tab

/* add this one line of CSS */
span { display: block; }

Some other important differences between inline and block:

Here is a good site for seeing what the default display value (inline or block) of every HTML element is: htmlreference.io

***

But there is also the possibility for elements to become inline-block. When you set something to display: inline-block, you essentially have the best of both worlds of block and inline. Things go in a flow (like inline), but they can take height and width properties (like block). Note that no elements are inline-block by default.

In the example, we changed the CSS so now <span> is now display: inline-block. Great! Now we have some blocks that go with the flow... indeed, the best of both worlds...

How would I define pebble? It’s a bit tricky, but if I were to start by the way of description, I should say that pebble is something somewhere between rock and stone. The obvious defect of my definition is that I can’t stop there: I have to continue defining stones and rocks all the way back to the flood and perhaps even further than that

View in new tab (try resizing browser window)

/* added a few new lines here */
span {
  display: inline-block;
  height: 140px;
  width: 140px;
  vertical-align: top;
  margin-bottom: 5px;
 }

When you position things with inline-block, you might also want to use the property vertical-align as well. With vertical-align you can align them in different ways, as we did here with vertical-align: top.

***

This philosophy could continue onto a whole site's design. If we design the way we read, which is left to right, top to bottom, then maybe we put the header or title in the first block... and the footer in the last.

β€œThe Pebble” (excerpt)

by Francis Ponge

How would I define pebble? It’s a bit tricky, but if I were to start by the way of description, I should say that pebble is something somewhere between rock and stone. The obvious defect of my definition is that I can’t stop there: I have to continue defining stones and rocks all the way back to the flood and perhaps even further than that

This way, when the page is viewed on mobile or small screens, it automatically works without having to do anything fancy. We are simply embracing the web's grain.

β€œThe Pebble” (excerpt)

by Francis Ponge

How would I define pebble? It’s a bit tricky, but if I were to start by the way of description, I should say that pebble is something somewhere between rock and stone. The obvious defect of my definition is that I can’t stop there: I have to continue defining stones and rocks all the way back to the flood and perhaps even further than that

View in new tab (try resizing browser window)

<header>
  <h1>β€œThe Pebble” (excerpt)</h1>
  <p>by Francis Ponge</p>
</header>
<span class="one">How would I define pebble?</span>
<span class="two">It’s a bit tricky,</span>
<span class="three">but if I were to start by the way of description,</span>
<span class="four">I should say that pebble is something somewhere between rock and stone.</span>
<span class="five">The obvious defect of my definition is that I can’t stop there:</span>
<span class="six">I have to continue defining stones and rocks all the way back to the flood</span>
<span class="seven">and perhaps even further than that</span>
<footer>
    <a href="https://francispongeonlineanthology.wordpress.com/2017/08/10/pebble-a-fragment-of-a-text-of-francis-ponge-translated-by-vadim-bystritski/">Source</a>
</footer>
body {
  text-align: center;
}

span,
header,
footer {
 width: 200px;
 height: 140px;
 display: inline-block;
 vertical-align: top;
 margin-bottom: 5px;
 text-align: left;
}

header {
 background: palegoldenrod;
}

footer {
   background: silver;
}

h1 {
 margin: 0;
 font-size: 1.5em;
}

Two important properties: display and position

The two properties display and position can do a lot of heavy lifting when it comes to CSS layout. Let's check them out...

β€œDisplay” property

We just looked at the common display values above.

But for the record, every element on a webpage is a rectangular box. (Remember the bookmarklet Boxify?) The display property determines exactly how that rectangular box behaves.

***

Want to center something horizontally on your page?

The method you use actually depends on the display value of your element.

To center a block element, you need to specify the element's height and width and also give it a margin left and right of auto.

from Domestic PensΓ©es

β€œA garden is not an object but a process”

Ian Hamilton Finlay (2004)

View in new tab

<!-- a div is a block element -->
<div class="quote">
    from <i>Domestic PensΓ©es</i><br><br>
    β€œA garden is not an object but a process”<br><br>
    Ian Hamilton Finlay (2004)
</div>
body {
    background: black;
}

.quote {
    width: 275px;
    margin: 2em auto;
    /* 
       the above line is shorthand for
       top and bottom margins = 2em
       left and right margins = auto
       more on margin property here:
       https://developer.mozilla.org/en-US/docs/Web/CSS/margin
    */
    padding: 1.5em;
    background: yellowgreen;
    border: 4px double black;
    border-radius: 25px;
}

To center an inline or inline-block element, the parent element (element the inline thing is inside of) should have text-align: center declaration.

A large painted sign of a strawberry advertising strawberries on the roadside

View in new tab

<figure class="image-container">
    <!-- an img is an inline element -->
    <img src="images/strawberry.png" alt="A large painted sign of a strawberry advertising strawberries on the roadside">
</figure>
.image-container {
    text-align: center;
    background: black;
    padding: 1.5em;
}

To center something vertically, that's a bit trickier. You'll find that in the Flexbox section below.

β€œPosition” property

The position property can help you manipulate the location of an element.

When you use either position: absolute or position: fixed, know that you’re removing that element from the normal β€œflow” of the web page. It’s good to keep in mind, especially as you start to think about websites that can easily adapt to smaller or larger screens (β€œresponsive design”).

When you use either position: absolute or position: fixed, you’ll need to then include specific declarations that specify where your element should be.

For example, here is a "sticker" that goes on top of our previous page. You will see in addition to having position: absolute, it also has top: 8px and right: 8px. These declarations tell it exactly where to go relative to the browser window.

How would I define pebble? It’s a bit tricky, but if I were to start by the way of description, I should say that pebble is something somewhere between rock and stone. The obvious defect of my definition is that I can’t stop there: I have to continue defining stones and rocks all the way back to the flood and perhaps even further than that

View in new tab

<div class="sticker"></div>
.sticker {
  position: absolute;
  top: 8px;
  right: 8px;
  height: 100px;
  width: 100px;
  border-radius: 50%;
  background: rgb(63, 94, 251);
  background: radial-gradient(
    circle,
    rgba(63, 94, 251, 1) 0%,
    rgba(252, 70, 107, 1) 100%
  );
}

Another important property that goes along with absolute and fixed positioning is z-index. Here we made the z-index: -1. z-index accepts integer values and lets you layer things below or on top of each other.

How would I define pebble? It’s a bit tricky, but if I were to start by the way of description, I should say that pebble is something somewhere between rock and stone. The obvious defect of my definition is that I can’t stop there: I have to continue defining stones and rocks all the way back to the flood and perhaps even further than that

View in new tab

.sticker {
  z-index: -1;
}

The relative position is good when you want something to be positioned absolutely in reference to its parent container...

How would I define pebble? It’s a bit tricky, but if I were to start by the way of description, I should say that pebble is something somewhere between rock and stone. The obvious defect of my definition is that I can’t stop there: I have to continue defining stones and rocks all the way back to the flood and perhaps even further than that

View in new tab

.container {
  width: 300px;
  margin: 2em auto;
  position: relative;
  padding: 0.5em;
  border: 1px solid gray;
}

Finally, this is an example where instead of absolute we used fixed, so the sticker stays in one place while the background moves when you scroll.

***

Here is an example of a layout using position: absolute and percentage values. Note that you can make this layout many ways, and this is just one of many ways to make it.

Fruitful Orchard
Welcome to our fruitful orchard! Please select a fruit on the brown menu to get started.
β€œπ’―π’½β„― π’»π“‡π“Šπ’Ύπ“‰ π“‡π’Ύπ“…β„―π“ƒπ“ˆ π“ˆπ“β„΄π“Œπ“π“Ž, π’·π“Šπ“‰ π’»π’Άπ“π“π“ˆ π“†π“Šπ’Ύπ’Έπ“€π“π“Žβ€

View in new tab

<header>Fruitful Orchard</header>
<main>
  Welcome to our fruitful orchard! Please select a fruit in the brown menu to get
  started.
</main>
<aside>
  Fruits
  <ul>
  <li>πŸ‡ Grapes</li>
  <li>🍈 Melon</li>
  <li>πŸ‰ Watermelon</li>
  <li>🍊 Tangerine</li>
  <li>πŸ‹ Lemon</li>
  <li>🍌 Banana</li>
  <li>🍍 Pineapple</li>
  <li>🍎 Apple (red)</li>
  <li>🍏 Apple (green)</li>
  <li>🍐 Pear</li>
  <li>πŸ‘ Peach</li>
  <li>πŸ’ Cherries</li>
  <li>πŸ“ Strawberry</li>
  <li>πŸ₯ Kiwi</li>
  <li>πŸ₯₯ Coconut</li>
  <li>πŸ₯­ Mango</li>
  </ul>
</aside>
<footer>β€œπ’―π’½β„― π’»π“‡π“Šπ’Ύπ“‰ π“‡π’Ύπ“…β„―π“ƒπ“ˆ π“ˆπ“β„΄π“Œπ“π“Ž, π’·π“Šπ“‰ π’»π’Άπ“π“π“ˆ π“†π“Šπ’Ύπ’Έπ“€π“π“Žβ€</footer>
header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  background: yellow;
}

aside {
  position: absolute;
  right: 0;
  bottom: 0;
  top: 3em;
  width: 30%;
  overflow-y: scroll;
  padding-bottom: 3em;
  background: sienna;
}

main {
  position: absolute;
  left: 0;
  bottom: 0;
  top: 3em;
  width: 70%;
  background: lime;
}

footer {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: cyan;
}

header,
main,
aside,
footer {
  padding: 1em;
}

header,
footer {
  text-align: center;
}

Units

In CSS, there are many different units you can use. When thinking responsively, it's good to remember there are certain units that might be better to use than others.

Here is an interesting example website where the font-size is using vw. Try resizing this and see how the font automatically scales depending on your browser width.

There are other units, but these are the most common!

Calc()

calc() is a native CSS way to do simple math right in CSS as a replacement for any number value. Being able to do math in code is nice and a welcome addition to a language that is fairly number heavy.

It has four simple math operators:

  1. add +
  2. subtract -
  3. multiply *
  4. divide /

And this math can be combined with any number of units. For example:

width: calc(100% / 12);

height: calc(100vh - 2em);

top: calc(400px - (10% + 2em));

Here are a couple use cases for calc().

Floats

an orange leaf floating serenely on dark water
float: right;

The idea of β€œfloats” comes from print layouts, where text wraps around an image on either left or right. On the web in CSS, the property float specifies that an element should be placed along the left or right side of its container, allowing text and inline elements to wrap around it. The element is removed from the normal flow of the web page, though still allowing other elements to wrap around it.

In the last few years, websites and social media platforms have introduced explore pages/tabs into their interfaces. Usually these are just feeds masquerading as explore pages. Other times they are simply static curated β€œstaff picks” lists, or personalized recommendation pages. To me, these pages don’t live up to the name β€œexplore”. A feed is based around time, usually sorted reverse chronologically, whereas an explore page reveals the expansiveness of a website by pulling from disparate sources, indifferent to time, allowing one to jump into the depths of something entirely new. Even personalized recommendation pages like Instagram’s explore tab aren’t really explore pages either because they are limited to a user’s interests/similarities to other users on the platform. Being fed similar content based on your likes isn’t the same as exploring the vastness of a platform. Explore pages are unique in that they unearth things that are not necessarily the most popular or the most recent. Interestingly, when explore pages are built this way it allows users to approach a platform with an open mind and with less expectations. Explore pages should make you feel a sense of excitement similar to the feeling of exploring a new place.

When I worked at The Creative Independent, we talked about creating an explore page, but we never got far enough along on the idea to define what the page would actually look like. One thing we did implement was a random button that served up a random interview from over 600 articles across the site. I ended up moving this button into the main navigation so that readers could continue to click the button until they found an interview that interested them. It’s fairly easy to implement a β€œrandomized items/articles” section on a website. In the case of The Creative Independent, this simple addition revealed how expansive the site really was.

View in new tab

video.left {
  float: left;
  margin-right: 1em;
  margin-top: 0.5em;
}

video.right {
  float: right;
  margin-left: 1em;
  margin-top: 0.5em;
}
<video width="320" controls class="left">
  <source src="stream1.mp4" type="video/mp4" />
</video>

<p>
  In the last few years, websites and social media platforms have
  introduced explore pages/tabs into their interfaces. Usually these are
  just feeds masquerading as explore pages...
</p>

<video width="320" controls class="right">
  <source src="stream2.mp4" type="video/mp4" />
</video>

<p>
  When I worked at <a href="https://indp.co">The Creative Independent</a>,
  we talked about creating an explore page, but we never got far enough
  along on the idea to define what the page would actually look like...
</p>

Note that sometimes you will need to clear your floats. You can see this in action in this example (where we try to recreate the previous layout but using float):

Fruitful Orchard
Welcome to our fruitful orchard! Please select a fruit on the brown menu to get started.
β€œπ’―π’½β„― π’»π“‡π“Šπ’Ύπ“‰ π“‡π’Ύπ“…β„―π“ƒπ“ˆ π“ˆπ“β„΄π“Œπ“π“Ž, π’·π“Šπ“‰ π’»π’Άπ“π“π“ˆ π“†π“Šπ’Ύπ’Έπ“€π“π“Žβ€

View in new tab

body {
  margin: 0;
}

header {
  background: yellow;
}

aside {
  float: right;
  width: 30%;
  overflow-y: scroll;
  background: sienna;
}

main {
  float: left;
  width: 70%;
  background: lime;
}

/* float is cleared for the footer */
/* as an experiment, try not having this clear and see what happens */
footer {
  clear: both;
  background: cyan;
}

Flexbox

(Since 2013)

Flexbox "aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic." Since it's still a newer technology, note that some older browsers don't support it. For more details, check out caniuse: flexbox.

Some useful resources for flexbox:

Vertical centering with flexbox

Welcome to my world!

View in new tab

body {
  
  /* vertical centering ... works on any child element */
  display: flex;
  align-items: center;
  justify-content: center;
  
  /* horizontal centering ... makes all text centered */
  text-align: center;
          
  /* delete the default margin on body */
  margin: 0;
  
  /* colors */
  background: black;
  color: white;
  
  /* responsive font size, 5% of viewport width */
  font-size: 5vw;
  
  /* by default body is as tall as its contents,
  and since we don't have much (just a sentence),
  we need to fill up body 100% viewport height */
  height: 100vh;
  
}
<body>
  <div class="sentence">Welcome to my world!</div>
</body>

There are multiple methods to vertically center an element in CSS, but we like using Flexbox for how simple it is. More info

<div> would definitely have to be my favorite element. I think it's so special. <div> is a little home for anyone and everything. And I love the CSS style of flexbox, and I love putting flex on divs. It’s my fav.

Here is an example of how to make the previous layout using flexbox.

Fruitful Orchard
Welcome to our fruitful orchard! Please select a fruit on the brown menu to get started.
β€œπ’―π’½β„― π’»π“‡π“Šπ’Ύπ“‰ π“‡π’Ύπ“…β„―π“ƒπ“ˆ π“ˆπ“β„΄π“Œπ“π“Ž, π’·π“Šπ“‰ π’»π’Άπ“π“π“ˆ π“†π“Šπ’Ύπ’Έπ“€π“π“Žβ€

View in new tab

The only thing to note is Flexbox isn't great for complex layouts like this, so we had to add one "container" element to make the middle two elements (lime and brown boxes) be side-by-side rather than on top of each other.

<header>Fruitful Orchard</header>
  <!-- this is the start of our new container -->
  <div class="body-container">
    <main>
      Welcome to our fruitful orchard! Please select a fruit in the brown menu to get started.
    </main>
    <aside>
      Fruits
      <ul>
        <li>πŸ‡ Grapes</li>
        <li>🍈 Melon</li>
        <li>πŸ‰ Watermelon</li>
        <li>🍊 Tangerine</li>
        <li>πŸ‹ Lemon</li>
        <li>🍌 Banana</li>
        <li>🍍 Pineapple</li>
        <li>🍎 Apple (red)</li>
        <li>🍏 Apple (green)</li>
        <li>🍐 Pear</li>
        <li>πŸ‘ Peach</li>
        <li>πŸ’ Cherries</li>
        <li>πŸ“ Strawberry</li>
        <li>πŸ₯ Kiwi</li>
        <li>πŸ₯₯ Coconut</li>
        <li>πŸ₯­ Mango</li>
      </ul>
    </aside>
  <!-- this is the end of our new container -->
  </div>
  <footer>β€œπ’―π’½β„― π’»π“‡π“Šπ’Ύπ“‰ π“‡π’Ύπ“…β„―π“ƒπ“ˆ π“ˆπ“β„΄π“Œπ“π“Ž, π’·π“Šπ“‰ π’»π’Άπ“π“π“ˆ π“†π“Šπ’Ύπ’Έπ“€π“π“Žβ€</footer>
  
body {
  margin: 0;
  display: flex;
  flex-direction: column;
}

header {
  background: yellow;
}

.body-container {
  display: flex;
  flex-direction: row;
}

aside {
  overflow-y: scroll;
  background: sienna;
  width: 30%;
}

main {
  background: lime;
  width: 70%;
}

footer {
  background: cyan;
}

However, one cool thing about flexbox (and CSS Grid, as you'll soon see) is that they were designed with responsiveness in mind. They are easily and powerfully paired with media queries.

The below code might not make sense yet, but essentially this media query says "When the browser is 768px or less wide, put the things that were side-by-side before as their own columns, and reverse their order, too!" Try resizing the example to a small width to see this in action.

@media screen and (max-width: 768px) {
  
  aside,
  main {
    width: 100%;
  }
  
  .body-container {
    flex-direction: column-reverse;
  }
  
}

CSS Grid

(Since 2017)

CSS Grid Layout is "a CSS layout method designed for the two-dimensional layout of items on a webpage or application." It allows for "complex responsive web design layouts more easily and consistently across browsers." Like Flexbox, it's still a newer technology, so some older browsers don't support it ... caniuse: grid.

Some useful resources for CSS grid:

Here is an example of how to make the previous layout using CSS Grid:

Fruitful Orchard
Welcome to our fruitful orchard! Please select a fruit on the brown menu to get started.
β€œπ’―π’½β„― π’»π“‡π“Šπ’Ύπ“‰ π“‡π’Ύπ“…β„―π“ƒπ“ˆ π“ˆπ“β„΄π“Œπ“π“Ž, π’·π“Šπ“‰ π’»π’Άπ“π“π“ˆ π“†π“Šπ’Ύπ’Έπ“€π“π“Žβ€

View in new tab

body {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(200px, 3fr) minmax(200px, 7fr);
  grid-template-rows: min-content 1fr min-content;
  height: 100vh;
}

header {
  background: yellow;
  grid-column: 1/-1;
}

aside {
  grid-column: 2/2;
  grid-row: 2/4;
  overflow-y: scroll;
  background: sienna;
}

main {
  grid-column: 1/2;
  background: lime;
}

footer {
  grid-column: 1/-1;
  background: cyan;
}

CSS Grid is very powerful but not the most intuitive. Explore the example links above for more info.

Important last details

The following small lines of code help tremendously when considering and coding responsive websites.

***

Remember to not forget this line of code in the <head> of your document:

<meta name="viewport" content="width=device-width,initial-scale=1.0">

Whenever a mobile device views the page, this line of code in the <head> makes sure the device doesn’t automatically resize the page but lets it appear the size it automatically is. (If you don't have this line, you might notice that your website is automatically scaling down when you view it on a mobile device.)

***

img { max-width: 100%; }

This line of CSS is very useful. It says that all images should be 100% of their parent's width unless they are smaller than their parent, and in that case, they wouldn't expand to fill their parent but just be the size they naturally are.

A large painted sign of a strawberry advertising strawberries on the roadside
A large painted sign of a strawberry advertising strawberries on the roadside
A large painted sign of a strawberry advertising strawberries on the roadside

View in new tab

<div class="large container">
  <img src="images/strawberry.png">
</div>

<div class="medium container">
  <img src="images/strawberry.png">
</div>

<div class="small container">
  <img src="images/strawberry.png">
</div>
img { max-width: 100%; }
.large { width: 333px; }
.medium { width: 222px; }
.small { width: 111px; }
.container { float: left; }

***

article { max-width: 800px; }

It's smart to use max-width, especially when dealing with blocks of text. In this previous example, the element article (containing all the text) has this CSS. Try resizing the page and seeing how the text automatically flows when the browser width gets smaller. If you used width instead of max-width, this wouldn't happen.

Part 3. Media Queries

Screen

Media queries are a type of CSS that allow content to adapt to various conditions. They are a fundamental technology of responsive web design. There is a lot of flexibility built into media queries β€” you can target specific screen widths, specific devices, or specific outputs (like print).

Here is an experimental example. Open this and try resizing your browser window to see what happens. Here is the CSS:

body {
  background: red;
  transition: background 300ms ease-in;
}

@media screen and (max-width: 768px) {
  body {
    background: yellow;
  }
}

@media screen and (max-width: 600px) {
  body {
    background: lime;
  }
}

@media screen and (max-width: 480px) {
  body {
    background: cyan;
  }
}

@media screen and (max-width: 320px) {
  body {
    background: magenta;
  }
}

Here is a more common example in which a menu changes for mobile use. Again, open this and try resizing your browser window to see what happens. Here is the HTML and CSS:

<nav>
  <ul>
  <li><a href="#">About</a></li>
  <li><a href="#">Blog</a></li>
  <li><a href="#">Garden</a></li>
  <li><a href="#">Thoughts</a></li>
  <li><a href="#">Feelings</a></li>
  </ul>
</nav>
nav {
  text-align: center;
  border-bottom: 1px solid black;
}

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

li {
  display: inline-block;
  list-style-type: none;
  margin: 0;
  padding: 1em 0.5em 1.5em;
}

a {
  color: black;
  text-decoration: none;
}

a:hover {
  background: yellow;
}

@media screen and (max-width: 420px) {
  ul {
    margin: 1em 0;
  }

  li {
    display: block;
    padding: 0.5em;
  }
}

The media query at the bottom says β€œonly apply these styles within this media query if your browser's viewport width is equal to or narrower than 420px.” So looking at those media queries inside, we see that, for example, the li is now display: block; instead of display: inline-block; as it was before. When it applies or the condition is true, the CSS within the media query overrides the other CSS.

Print

Here is another website example. This time, instead of resizing the browser window, try printing the website and saving as a PDF. See if you notice any changes between the website and the PDF.

Here a fragment of that website's CSS:

@media print {
   #keyboard-arrows {
     display: none;
   }
   #side-column {
     height: auto;
     overflow:hidden;
   }
   #main-column {
     width: 100%;
     margin: 0;
     height: auto;
     position: relative;
   }
   li.current path {
     fill: #000000 !important;
     color: #000000 !important;
   }
   li:not(.current) {
     display: none !important;
   }
}

The above are overrides for when the website is printed. They are here so that the "next" arrow button doesn't appear on the printout or the side column doesn't appear, for instance.

Other media queries

There are other uses for media queries, such as enabling custom CSS for light and dark modes and for screen readers. You can read more on Mozilla's media queries page.

Part 4. Example

screenshot of The Creative Indpendent website that relies on many items inline or inline-block

When Laurel was first designing The Creative Independent's homepage, she decided on a strategy of using many elements that were display: inline or display: inline-block because the website was made to grow. She didn't know how many menu items there might be, so she wanted to create a flexible system.

***

So to start something like TCI's homepage, let's start with a sketch. You'll see there are boxes inside of boxes, or elements inside of elements. Classic nesting tendency of HTML... it's good to think this way.

After making the sketch (and thinking which things are inside of which things), you can go to code. Here is a simplified TCI homepage following the sketch. Feel free to check out the source code, and remember to try resizing the page! :)

πŸ”— Further CSS layout resources

(Some repeated from above)

πŸ‹ Try this

Demo: Fruitful social media profile

Create a profile page for yourself on the "Fruitful Orchard," a hypothetical social media where all you do is show 10 pics from your camera roll. This is a good excuse to try some new things with CSS layout ... including responsive design (sizing down to mobile) if you're up for it, using media queries!

requirements:

Watch our demo video for reference:

Watch on YouTube John's profile code Laurel's profile code

When you're done, upload this file to your personal demos/demo3/ folder in the portal.