ProNextJS
    Loading
    lesson

    Create a Layout with CSS Modules

    Jack HerringtonJack Herrington

    In this section of the tutorial, we're going to focus on CSS modules. CSS modules are baked into Next.js, and if you just want to do CSS, CSS modules are the way to do it.

    A Preview of the Final Result

    As we go through this example, this is what we're going to be looking for in terms of the final result:

    Polypane screenshot

    We can see that we've got a dark mode view of both the mobile size and the desktop size. A commercial application called Polypane is used here to look at multiple sizes simultaneously, as well as toggling dark mode. However, you can use any browser you like.

    Let's start working on the CSS that gets us to the final result.

    Starting the Development Server

    Start the development server by running:

    pnpm dev
    

    You should see the completely unstyled application:

    Unstyled application

    Back in VS Code, we'll start building out the CSS layout.

    Constraining the Page Width

    The first thing we want to do is constrain the width of the page and then move it in from the sides. We want to set a boundary of 960 pixels and then adjust it from the sides.

    To do that, we're going to create a new file inside of src/app called page.module.css to specify a CSS module. Anything inside of this file is going to be CSS and will be usable as a CSS module.

    Inside of the file, we'll create a CSS class like you normally would in any CSS file. We'll call it main:

    /* inside of page.module.css */
    .main {
      max-width: 960px;
      margin: 0 auto;
    }
    

    Now in the page.tsx file, we'll import the styles:

    // inside page.tsx
    
    import styles from './page.module.css';
    

    Then, to use the main class from the styles, we simply use className and set it to styles.main:

    // inside the Home component
    <main className={styles.main}>
    

    The underlying CSS modules mechanism baked into Next.js is going to take that CSS from the CSS file, then statically generate it into a CSS file that is then associated with the application.

    After saving our work, we can see in Polypane that it brought the content in from the sides a little bit. The effect is subtle, but it's there.

    Polypane preview with constrained widths

    Looking in browser DevTools, notice how class names include a hash similar to this:

    <body class="__className_aaf875">
    

    The cool thing about CSS modules is that the generated CSS gives you good encapsulation, meaning you can have the same class name in multiple components without collisions.

    Creating a Three-Column Layout

    The next thing to do is create a three-column layout for the desktop mode. We're going to use Flexbox for that, and main is going to control that as well.

    Back in the page.module.css file, set the display mode to flex:

    .main {
      max-width: 960px;
      margin: 0 auto;
      display: flex;
    }
    

    Now we've got a Flexbox, it's a flex row, but it's continuing on ad infinitum:

    flex row

    That's not good. We need to tell it to wrap when it reaches the edge of the container. To do that, we specify flex-wrap and set the mode to wrap:

    .main {
      max-width: 960px;
      margin: 0 auto;
      display: flex;
      flex-wrap: wrap;
    }
    

    After saving, it's starting to look like a decent layout:

    The wrapped cards

    Styling the Product Card

    The next thing to do is start styling the card.

    Inside of the page.module.css file we'll add a card class and some media queries:

    .card {
      padding: 0.2rem;
    }
    
    @media screen and (max-width: 768px) {
      .card {
        width: 100%;
      }
    }
    
    @media screen and (min-width: 768px) {
      .card {
        width: 33%;
      }
    }
    

    Your task is to apply the card class to the <div> that wraps the product card in the Home component in the page.tsx.

    In the next lesson, we'll pick up from there.

    Transcript