Creating Columns: Intro to CSS Grid & Media Queries

Free HTML & CSS Tutorial

Delve into the intricacies of HTML and CSS, as this tutorial guides you through creating a 2-column layout, identifying an ideal breakpoint, and implementing a media query to alter the layout depending on screen size.

This exercise is excerpted from Noble Desktop’s past front-end web development training materials and is compatible with updates through 2022. To learn current skills in web development, check out our coding bootcamps in NYC and live online.

Note: These materials are provided to give prospective students a sense of how we structure our class exercises and supplementary materials. During the course, you will get access to the accompanying class files, live instructor demonstrations, and hands-on instruction.

Topics covered in this HTML & CSS tutorial:

Creating a 2-column layout with CSS Grid, Finding an appropriate breakpoint, Using a media query to change the layout at a specific screen size

Exercise Preview

preview grids

Front End Web Design Certificate: Live & Hands-on, In NYC or Online, 0% Financing, 1-on-1 Mentoring, Free Retake, Job Prep. Named a Top Bootcamp by Forbes, Fortune, & Time Out. Noble Desktop. Learn More.

Exercise Overview

In this exercise, you’ll use CSS to define a grid of columns and rows to layout the page. You’ll also learn how to change the layout based on screen size, making the design switch from a 1-column layout on small screens, to a 2-column layout on larger screens.

Getting Started

  1. In your code editor, close any files you may have open.
  2. For this exercise we’ll be working with the Resume folder located in Desktop > Class Files > Web Dev Class. You may want to open that folder in your code editor if it allows you to (like Visual Studio Code does).
  3. Open resume.html from the Resume folder.
  4. Preview resume.html in Chrome. (We’re using Chrome because we’ll be using its DevTools later.)
  5. Notice that the page is mostly styled. We’re going to focus on putting the Work Experience section on the left and the Education section on the right so we have a 2-column layout.

    NOTE: We recommend leaving resume.html open in the browser as you work, so you can reload the page to see the changes you make in the code.

  6. Let’s take a quick look at the HTML markup. Switch back to your code editor.
  7. Take a look at the code to familiarize yourself with the basic page structure, focusing on the following elements:

    • On line 11 notice there is wrapper div. This is the parent container for all the content on the page.
    • Inside main (starting on line 15) are 3 primary sections, each with a unique id.
    • We want the statement section (on line 16) to span 2 columns, above the experience section (on line 20) as one column on the left, and the education section (on line 55) as another column on the right.
  8. Let’s start styling. Open main.css from the Resume folder.

Creating a 2-Column Layout with CSS Grid

To make columns we’ll define a grid which indicates how many columns we want and how wide we want them to be. We define the grid on the parent element which contains the elements we want to be become columns and rows in the grid.

  1. At the bottom below all the other rules, add the following new rule:

    main {
       display: grid;
       grid-template-columns: 2fr 1fr;
    }
    

    NOTE: The fr unit is a fr actional unit. According to the spec tinyurl.com/fr-unit an fr unit “represents a fraction of the leftover space in the grid container”. So another way to think of fr is that it stands for “free space”. First the browser calculates the size of grid items with specific widths (such as pixels), then takes the leftover free space and distributes it between the grid tracks with fr units.

  2. Save main.css.
  3. Switch to the browser and reload resume.html.

    While the Statement of Intent currently looks weird where it is (we’ll fix that next), we do have 2 columns, with the left column being twice the width as the right column. There is also a second row down below, which contains the Education section (in the left column of that second row).

    Let’s make the Statement of Intent span across the 2 columns.

  4. Return to main.css in your code editor.
  5. At the bottom below all the other rules, add the following new rule:

    #statement {
       grid-column: span 2;
    }
    
  6. Save main.css and reload resume.html in the browser.

    Much better! It could use some space between the columns and rows though.

  7. Switch back to main.css in your code editor.
  8. In the main rule, add the gap property (highlighted below in bold):

    main {
       display: grid;
       grid-template-columns: 2fr 1fr;
       gap: 30px;
    }
    
  9. Save main.css and reload resume.html in the browser to see that the columns now have space between them.

    This looks great on a wide screen, but small screens don’t have enough space for multiple columns.

Finding an Appropriate Breakpoint

Let’s see how to change the layout across screen sizes.

  1. To simulate a small screen, make the browser window as narrow as possible and notice two problems:

    • The 2-column layout looks fine when the window is wider, but they’re very hard to read when the window is narrow (like a phone). We should switch to a single-column layout for small screens.

    • When the window is narrow, it would be better if we didn’t have the gray area around the page, so more of the screen space would be used for content.

  2. Make the window wide again.

    We need to find a good breakpoint, a point at which the layout needs to change. Let’s open the DevTools so we can see the browser’s width and height—a feature that’s unique to Chrome’s DevTools.

  3. Open Chrome’s DevTools using the following keystroke:

    • Mac: Hit Cmd–Opt–I (that’s a letter i, not the number 1) or F12 (you may have to hold the fn key when hitting F12 on some keyboards).
    • Windows: Hit Ctrl–Shift–I (that’s a letter i, not the number 1) or F12 (you may have to hold the fn key when hitting F12 on some keyboards).
  4. Slowly resize the browser window while looking at the top-right corner of the preview area to see the pixel width and height of the visible area.
  5. Find a width where you think the 2-column layout starts looking cramped and we should switch to 1-column. It’s a matter of opinion, but we think that this point is around 700 pixels wide so we’ll use this as a breakpoint.
  6. For best results the next time we preview the page:

    • Make sure the browser window is narrower than our breakpoint of 700 pixels.
    • Leave both the page and the DevTools open in Chrome so we can come back to them later.

Using a Media Query to Change the Layout at a Specific Screen Size

To change the layout at our 700 pixel breakpoint, we will use a CSS media query. CSS media queries let us apply have CSS that only works if certain conditions are true, such as a specific screen size, screen resolution, type of device, etc. If these conditions are not met, the CSS rules are ignored.

  1. Switch back to main.css in your code editor.
  2. Let’s start by removing the gray space around the page on small screens, so we can add it back on large screens. This space was created using margin on the body tag. At the very top of the file, change margin to 0 as shown below:

    body {

    Code Omitted To Save Space

       background: #9e9ea0;
       margin: 0;
    }
    
  3. Save main.css.
  4. Switch to Chrome and reload resume.html to see the gray around the page should be gone.
  5. Switch back to main.css in your code editor.
  6. At the bottom of the file below all the other rules, write the media query shown below in bold:

    #statement {
       grid-column: span 2;
    }
    
    @media (min-width: 700px) {
    
    }
    

    Let’s break down that code:

    • The code in parentheses is the query (the condition to test).
    • In the curly braces we’ll add CSS rules that we want to apply if the query is true.
    • For querying browser/screen width we can use min-width and max-width. We used min-width, so the CSS we’ll add inside the media query will only apply to screens that are 700px or wider.
  7. Now that we have a way to target large screens, we can add the body margin back in (to create the gray space around the page). Add the following bold code:

    @media (min-width: 700px) {
       body {
          margin: 20px;
       }
    }
    

    NOTE: This new rule in the media query will override the body rule at the top of the file, but only when the browser is 700px or wider.

    Media Queries & CSS Style Order

    If two rules have the same specificity, the latter will win. This is why media queries are put below the general styles. The rules in a media query will only apply if the condition is met, and will then override the general styles.

  8. Save main.css.
  9. Switch to Chrome and reload resume.html. Because you left the window narrower than 700px, the gray space around the page should NOT be visible.
  10. Slowly resize the browser window to be wider. BOOM! Once we hit the breakpoint of 700 pixels, the gray space around the page should all of a sudden appear!
  11. Resize the browser window to be narrower than 700px and notice the gray space around the page disappears (so there’s more room for the content). As you can see, the rule inside our media query only applies when the condition is met. Otherwise the browser ignores the rule.

    Mobile First

    CSS at the top (not in a media query) applies to all screen sizes (mobile and larger). The min-width media query only applies to larger screens. The approach of starting with small screens and then larger screens is called “mobile first”.

  12. Switch back to main.css in your code editor.
  13. One smaller screens (like phones) we want a single column layout. Then on large screens (like tablets and desktop) we want a 2 column layout. In the main rule change the grid-template-columns property to 1fr (highlighted below in bold):

    main {
       display: grid;
       grid-template-columns: 1fr;
       gap: 30px;
    }
    

    NOTE: This makes it one column that takes up all the free space.

  14. Save main.css.
  15. Switch back to Chrome and reload resume.html.

    The span on the Statement of Intent is still forcing 2 columns to be made, so we’ll need to move that code into the media query for large screens.

  16. Switch back to main.css in your code editor.
  17. Select and cut the #statement rule.
  18. At the end of the media query, paste it so you get the following:

    @media (min-width: 700px) {
       body {
          margin: 20px;
       }
       #statement {
          grid-column: span 2;
       }
    }
    
  19. Save main.css.
  20. Switch back to Chrome and reload resume.html.

    Now the layout only has one column. That’s good, this applies to all screen sizes, not only phones. Let’s make the larger screens have 2 columns again.

  21. Switch back to main.css in your code editor.
  22. In the media query, add a new rule for main as shown below in bold:

    @media (min-width: 700px) {
       body {
          margin: 20px;
       }
       main {
          grid-template-columns: 2fr 1fr;
       }
       #statement {
          grid-column: span 2;
       }
    }
    
  23. Save main.css.
  24. Switch back to Chrome and reload resume.html.
  25. Resize the browser window in and out to see that all the elements are displayed in a single column until it reaches 700 pixels or wider, when the rules that comprise our 2-column layout kick in.

Disabling Mobile Browser Text Size Adjustment

  1. On the upper left of the DevTools panel, click the Toggle device toolbar button devtools device mode icon to open the mobile simulator.
  2. Above the webpage preview, select a device such as the iPhone 5/SE:

    device preview choose iphone resume

  3. Click the Reload button, or hit Cmd–R (Mac) or Ctrl–R (Windows).
  4. Notice that for the most part it looks like the desktop layout has been scaled down. It’s not the one column layout we want for mobile devices. That’s one issue we need to fix. But first, notice that some text (such as the heading and first paragraph) has not been reduced as much as other text (such as the two columns). That’s because some mobile browsers enlarge text they think is too small (if they think it doesn’t break the layout). We don’t want mobile browsers arbitrarily overriding some our font sizes, so let’s disable that.
  5. Switch back to your code editor.
  6. Go to Resume > snippets and open a code snippet we prepared for you, text-size-adjust.css.
  7. Hit Cmd–A (Mac) or Ctrl–A (Windows) to select all the code.
  8. Hit Cmd–C (Mac) or Ctrl–C (Windows) to copy it.
  9. Close the file.
  10. At the top of main.css, paste the new code above the body rule:

    html {
       -moz-text-size-adjust: 100%;
       -webkit-text-size-adjust: 100%;
       text-size-adjust: 100%;
    }
    body {
    
  11. Save the file.
  12. Switch back to Chrome and reload the page.
  13. The text is no longer being enlarged, so it looks like the desktop layout scaled down to fit a mobile phone. Now that the browser won’t be deciding what text it might enlarge, we must get it to display the layout appropriately for small screens, instead of scaling down the desktop layout.

The Viewport Meta Tag

Mobile devices assume websites were designed for desktops. They render the site on a large viewport (980px) and scale it down to fit their smaller screen. For responsive sites we must add a meta tag to tell it to render the page at the actual pixel width of the device, instead of the default 980px.

  1. Keep the browser open in device mode so we can come back to preview the changes we’re about to make.
  2. In your code editor, switch to resume.html.
  3. In the <head> tag, add the following bold code:

    <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1">
       <title>John Jacob J. Schmidt’s Resume</title>
    

    This tells mobile browsers to make the width of the viewport equal to the width of the device. Like other meta tags, it goes in the head tag.

  4. Save the file and reload the page in Chrome (which should still be in device mode).

    Now it should be the correct one column mobile appropriate layout! The viewport meta tag does not affect desktop browsers, only mobile browsers which employ the scaling behavior. As shown below, on the left is how the page looked before the meta tag, and on the right we see it with the meta tag!

    viewport meta tag before after resume

Optional Bonus: Adjusting Text Size Across Screens

The John Jacob J. Schmidt heading (an h1) looks good on desktops, but is too big on phones. Let’s adjust that.

  1. Switch back to main.css in your code editor.
  2. In the h1 rule, change font-size to 32px.
  3. To make the text larger on desktops only, inside the media query add the following new rule (shown below in bold):

    @media (min-width: 700px) {
       body {
          margin: 20px;
       }
       h1 {
          font-size: 42px;
       }
    
  4. Save main.css and reload resume.html in Chrome.

    The phone layout now looks perfect, but let’s check the desktop size one last time.

  5. In the upper left of the DevTools panel, click the Toggle device toolbar button devtools device mode icon to close the mobile simulator.
  6. Close the DevTools panel.

    The desktop layout also looks great!

Older Way to Write a Media Query

You may see media queries written using the older approach shown below, but we feel this is unnecessarily verbose for modern browsers.

@media only screen and (query) {
   /* CSS rules go here */
}

How to Learn HTML & CSS

Master HTML and CSS with hands-on training. HTML (HyperText Markup Language) and CSS (Cascading Style Sheets) are used to build and style webpages.

Yelp Facebook LinkedIn YouTube Twitter Instagram