Creating a responsive web design with a user-friendly CSS grid layout

Currently, I am delving into the realm of CSS grid to better comprehend its functionality. In my layout design, there are two menus (colored in red) positioned on either side of a central main content box (colored in blue).

As the screen size reduces and accommodation for three columns becomes unfeasible, my objective is to have the second menu (on the right side) shift directly below the first one (on the left side).

https://i.sstatic.net/5hYKH.png

The height variations among the main content and side menus are arbitrary, as their heights depend on the quantity of content or menu items they contain. The solution should remain effective regardless of these height discrepancies.

The current layout is almost flawless, with the minor issue being that the second menu appears below the conclusion of the main content rather than directly following the first menu. How can this be rectified?

.main-container {
  width: 100%;
  height: 100%;
}

@media only screen and (min-width: 400px) {
  .main-container {
    display: grid;
    grid-gap: 20px;
    grid-template-columns: 40px 80px 40px;
    justify-content: center;
  }
}

@media only screen and (max-width: 400px) {
  .main-container {
    display: grid;
    grid-gap: 20px;
    grid-template-columns: 40px 80px;
    justify-content: center;
  }
}

.side-menu {
  width: 100%;
  height: 50px;
  background-color: red;
}

.main-content {
  width: 100%;
  height: 300px;
  background-color: blue;
}
<div class="main-container">
  <div class="side-menu"></div>
  <div class="main-content"></div>
  <div class="side-menu"></div>
</div>

In adherence to the title's instruction "CSS grid layout," I am aiming to achieve this without resorting to JavaScript.

Answer №1

No rows have been specified in the grid:

.main-container {
  display: grid;
  grid-gap: 20px;
  grid-template-columns: 40px 80px 40px;
  justify-content: center;
}

Because of this, all rows are automatically generated to accommodate items, known as implicit rows.

The sizing function for implicit rows is defined using grid-auto-rows with a default value of auto, making the rows adjust based on content size.

The height has been set for grid items:

.side-menu {
  height: 50px;
}

.main-content {
  height: 300px;
}

Thus, the height of the row is determined by the tallest item, which is .main-content:

https://i.sstatic.net/u8iiF.png

The grid container consists of one row according to the setup.

Upon reaching smaller screen sizes, the media query comes into play:

@media ( max-width: 400px ) {
  .main-container {
    grid-template-columns: 40px 80px;
  }
}

This modification changes the grid from three columns to two, resulting in the creation of a new implicit row to fit the second .side-menu due to column adjustments:

https://i.sstatic.net/T1PSA.png

In summary, a second row is added beneath the first, causing a significant vertical gap between the menus.


Potential Resolution

To address this issue, consider using multiple smaller rows and expanding your items across them. The model below demonstrates this concept:

https://i.sstatic.net/NR6pa.png

.main-container {
    display: grid;
    grid-template-columns: 40px 80px 40px;
    grid-auto-rows: 10px;  /* new */
    grid-column-gap: 20px; /* adjusted */
}

.side-menu:first-child {
  /* height: 50px; */
  grid-column: 1;
  grid-row: span 5;
}

.side-menu:last-child {
  /* height: 50px; */
  grid-column: 3;
  grid-row: span 5;
}

.main-content {
  /* height: 300px; */
  grid-column: 2;
  grid-row: span 30;
}

@media ( max-width: 400px ) {
  .main-container {
    grid-template-columns: 40px 80px;
  }
  .side-menu:last-child {
    grid-column: 1;
    grid-row: 7 / span 5;
  } 
}

.main-content { background-color: blue; }
.side-menu    { background-color: red;  }
<div class="main-container">
  <div class="side-menu"></div>
  <div class="main-content"></div>
  <div class="side-menu"></div>
</div>

Explore CodePen Demo

Answer №2

To effectively utilize media screen, consider setting up 2 rows for the task at hand. Additionally, I recommend using "fr" units instead of pixels in grid layout.

For more detailed instructions, check out this helpful guide here.

.main-container {
      width: 100%;
      height: 100%;
    }

    @media only screen and (min-width: 400px) {
      .main-container {
        display: grid;
        grid-gap: 20px;
        grid-template-columns: 40px 80px 40px;
        grid-template-rows: 40px;
        justify-content: center;
        grid-auto-flow: rows;
      }
      .side-menu:nth-child(odd) {
      width: 100%;
      height: 50px;
      background-color: red;
        grid-column: 1;
      }

      .side-menu:nth-child(even) {
      width: 100%;
      height: 50px;
      background-color: red;
        grid-column: 3;
      }
    }

    @media only screen and (max-width: 400px) {
      .main-container {
        display: grid;
        grid-gap: 20px;
        grid-template-columns: 40px 80px;
        grid-auto-rows: 40px;
        justify-content: center;
      }

      .side-menu {
      width: 100%;
      height: 50px;
      background-color: red;
        grid-column: 1;
      }
    }


    .main-content {
      width: 100%;
      height: 300px;
      background-color: blue;
    }
<div class="main-container">
  <div class="side-menu"></div>
  <div class="main-content"></div>
  <div class="side-menu"></div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Custom HTML select element not triggering the onchange event

I found a code snippet on https://www.w3schools.com/howto/tryit.asp?filename=tryhow_custom_select that demonstrates a custom select input with an onchange event. However, I am facing an issue where the onchange event does not get triggered when I change th ...

Steps for incorporating a storyline into a CSS Chart

I'm attempting to introduce a horizontal line at a specific point using chartscss.org For instance, on the given chart utilizing Charts CSS below, I'm aiming to include a horizontal line at 15.5... Similar to the illustration shown. I've e ...

The nested div does not have scrolling functionality

I'm currently working on making a nested div scrollable, but I'm encountering some challenges. The problematic div in question is the one with the "items" class. <body> <div class="page-wrapper"> <div class="header">Heade ...

Canvas in the off state has been removed

My goal is to create a basic JavaScript library that includes rotating, translating, and scaling the canvas. One issue I am facing is when I rotate the canvas, half of the content ends up getting deleted because the center of rotation is set at (0, 0). I ...

The submit button appears as grey on IOS when using the input[type="submit"]

Why does the submit input look different on IOS only, and how can this be resolved? https://i.sstatic.net/UVlKB.png Thank you in advance For HTML: <input class="btn" type="submit" [disabled]="" ...

Absolute positioned content causing unexpected spacing on top of relative positioned content

I've been experimenting with a fantastic technique by Chris Coyier for implementing full page video backgrounds with content scrolling over the video. However, I've encountered an issue where there's an unexpected gap to the right in Windows ...

Adjusting data points on a radar chart.js through user interaction

I have a radar map generated using chart.js, along with some input fields where users can enter values that I want to reflect in the graph. I am exploring ways to update the chart dynamically as the user types in the values. One option is to have the char ...

Conceal elements of a rectangular shape using CSS

https://i.stack.imgur.com/ebaeI.jpg I need help hiding the second rectangular shape on my website. I want the width to be 100% and responsive, but whenever I use position: absolute; with right:-10%, it's not working as expected. Even trying body { ma ...

How to trigger a hover effect on a div and its child simultaneously using HTML and jQuery

Here's my concept: I want the text to be contained within div elements with an integrated image, rather than just having fading in and out pictures. Here's my attempt: #first{ position: absolute; } #second{ position: absolute; -we ...

Sliding Up Transition Effect for Footer with JQuery or CSS3

I am attempting to replicate a sleek slide up footer that caught my eye on The Internship Movie Site. I have created the wireframe layout, but I am struggling to figure out the correct CSS transition effect. Although I have experimented with the "top" and ...

Optimizing Static File Caching in Yii

Having a frustrating issue with Yii where my local development environment caches CSS and JS files. Despite making changes to the file, the edits do not reflect in the output and sometimes causes corruption leading to broken functionality. This problem see ...

Troubleshooting: Issues with jQuery's Class selector

Having trouble setting up an alert to trigger when a specific class anchor tag is clicked inside a div. This is what my HTML section looks like... <div id="foo"> <a class='bar' href='#'>Next</a> </div> And h ...

Applying CSS to color the letters of a text, without needing to alter the HTML code

I'm just beginning to learn CSS and today I received a school assignment: Below is the HTML code provided: <head> <meta charset="UTF-8"> <title>ABC</title> <style> /* CSS section */ </style> ...

When I apply position: absolute; to my navigation bar, the anchor tags and links do not seem to function properly, especially with a video playing in the background

How can I make my anchor tags/links work properly on a header with a video in the "background" and a menu on top? HTML <nav class="menu"> <a href="#" target="_blank">ABOUT</a> <a href="#" target="_blank">PRICES</a&g ...

What is the most effective way to extract information from a .txt file and showcase a random line of it using HTML?

As a newbie in HTML, my knowledge is limited to finding a solution in C#. I am attempting to extract each line from a .txt file so that I can randomly display them when a button is clicked. Instead of using a typical submit button, I plan to create a custo ...

The submenu background and text CSS are out of alignment

Within the main navigation of our Wordpress website, built using the Divi Page Builder, there are two submenus. The issue arises when hovering over the main navigation item and then leaving the submenu - at that point, both the background and the text disa ...

Sending AJAX data by clicking a link in Laravel 5

I am new to working with ajax and Laravel 5 I am facing some issues with passing data when clicking on a link. Let me explain what I am trying to achieve. Here is my HTML code: //this is the div that I want to append with data for each <div id="warun ...

What is the best way to create a border that surrounds a collection of pictures?

I'm currently facing a challenge in getting a border to perfectly fit around a collection of images. The issue can be observed in this Jsfiddle I shared, where the border aligns with the top and left edges, but not with the bottom and right edges. Her ...

Increased pixels being incorporated into my line spacing

Looking for a solution: A <div> containing only one word at a font size of 16px with a line-height set to 1. Encountering issues with extra space above the text in Chrome and Firefox, while the text bleeds slightly out of the bottom. IE exacerbates t ...

Is there a way to prevent one accordion pattern from automatically closing when another one is opened?

I'm currently working on a code that involves accordion patterns, and I've encountered an issue where opening and closing one accordion automatically closes another. I want all accordions to remain open until the user explicitly clicks to close t ...