CSS Grid: Rows not maximizing available vertical space

I am trying to create a simple layout using CSS grid instead of flexbox:

https://i.sstatic.net/xjEy0m.jpg

Currently, I have something similar but with an unwanted white area:

https://i.sstatic.net/IEe2Wm.jpg

My question is, what am I missing in my code to achieve the desired layout?

The issue seems similar to these questions: How to make CSS Grid items take up remaining space?
And this one: How do you collapse unused row in a CSS grid?

However, it's a bit more complicated since I have an extra row

I have a green div on the last row that needs to grow with the page height.
To achieve that, the row template for this last row is set to 1fr.

Here is my current code:

You can view the simple code snippet below:

html {
    height: 100%;
}
body {
    height: 100vh;
}
.container {
    display: grid;
    grid-template-columns: 180px 1fr;
    grid-template-rows: min-content auto 1fr;
    height:100%;
}

.red-cube {
    background-color: red;
    width: 100%;
    Height: 180px;
    grid-column: 1;
    grid-row: 1 / 3;
}
h1, h2 {
    margin: 0;
    padding: 0;
}
.blue-title {
    background-color: blue;
    grid-column: 2;
    grid-row: 1;
    height: fit-content;
}
.yellow-div {
    background-color: yellow;
    grid-column: 2;
    grid-row: 2;
    height: 100%;
}
green-content {
    background-color: green;
    grid-column: 1 / 3;
    grid-row: 3;
    align-self: stretch;
}
<div class="container">
    <div class="red-cube"></div>
    <h1 class="blue-title">Title</h1>
    <div class="yellow-div"><h2>Second line</h2></div>
    <div class="green-content"><p>Some text</p></div>
</div>

Feel free to play around with the code snippet on Codepen here.

Attempted Solution:

I tried setting the grid-template-rows value of the yellow row to 1fr to fill the remaining space. However, this broke the green div that should grow with the page height as we would then have two rows with a setting of 1fr.

In Conclusion:

I'm curious if there is a solution that doesn't involve switching to flexbox or restructuring the layout into multiple grid layouts.

I also want to avoid "hardcoding" the row heights by using something like:

grid-template-rows: 1.25rem auto 1fr;

Answer №1

In order to address this issue, consider implementing a nested grid arrangement instead (not to be confused with subgrid). Reallocate the .green-content div outside of the .container grid. To do this, configure the body as a grid with two rows - the first row set to a height of 180px and the second row expanding with a height of 1fr. The 180-pixel row will serve as the parent for the .container grid. Keep in mind that if you prefer not to utilize the entire page, an alternative element can be designated as the parent grid. Provided below is a functional example:

html {
    height: 100%;
}

body {
    height: 100vh;
    display: grid;
    grid-template-rows: 180px 1fr;
}

.container {
    display: grid;
    grid-template-columns: 180px 1fr;
    grid-template-rows: max-content 1fr;
}

.red-cube {
    background-color: red;
    width: 100%;
    height: 180px;
    grid-column: 1;
    grid-row: 1 / 3;
 }

h1, h2, p {
    margin: 0;
    padding: 0;
}

.blue-title {
    background-color: blue;
    grid-column: 2;
    grid-row: 1;
    height: fit-content;
 }

 .yellow-div {
    background-color: yellow;
    grid-column: 2;
    grid-row: 2;
    height: 100%;
 }

.green-content {
    background-color: green;
    margin-top: 0;
}
<div class="container">
    <div class="red-cube"></div>
    <h1 class="blue-title">Title</h1>
    <div class="yellow-div"><h2>Second line</h2></div>
</div>
<div class="green-content"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ac accumsan eros. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed dictum in magna eu luctus. Fusce feugiat lectus tortor, eget consectetur augue convallis non. Aliquam massa tortor, fermentum eu nibh non, sollicitudin molestie mi. Ut nec eros sagittis sapien tristique accumsan. Vivamus dapibus, nulla vitae facilisis volutpat, velit odio viverra nisl, non tempor erat mi condimentum velit. Duis posuere sem arcu, venenatis condimentum lorem efficitur eu. Quisque et mi quis lorem pellentesque ultrices. Ut felis lacus, vestibulum sit amet libero non, viverra condimentum turpis. Phasellus massa quam, vestibulum sit amet fermentum molestie, egestas in velit. Donec tristique tempus urna. Nullam pellentesque volutpat mattis. Nunc volutpat orci vel dolor ultrices vestibulum.

Aenean volutpat lacus vitae vehicula semper. Nunc volutpat auctor ligula. Nulla sed augue sem. Vestibulum suscipit ante ac mi viverra, quis feugiat orci posuere. Quisque sit amet tortor luctus, mollis neque a, varius velit. Maecenas sed pulvinar eros, at pretium diam. Duis tellus leo, blandit eget turpis eu, ultricies condimentum dolor. Aliquam erat volutpat. Duis convallis enim lacus, vitae placerat dui dictum convallis. Suspendisse viverra magna vel tellus condimentum, vel pharetra lacus rhoncus. Nam quis mattis elit. Nullam ultricies metus odio, a lobortis quam pharetra sed. Suspendisse vestibulum ullamcorper neque, condimentum euismod ex venenatis ac. Aenean vitae ex eget ligula ultricies condimentum. Donec quis nibh nec massa rutrum dignissim non eget tortor.

Praesent sollicitudin varius diam vel hendrerit. Ut sit amet finibus turpis, sit amet rutrum quam. Sed vestibulum tortor vel quam viverra ullamcorper. Aliquam erat volutpat. Sed gravida, risus vitae dignissim ornare, felis ante vestibulum sapien, nec tempor eros arcu in enim. Nullam suscipit mollis arcu non aliquet. Aenean sit amet nisl dui. In euismod turpis et velit pellentesque fringilla. Ut ut quam lobortis neque egestas pulvinar ac nec ante. Donec tortor odio, posuere eget congue vitae, accumsan eget nisl. Curabitur nunc urna, elementum id erat a, viverra maximus eros. Proin dictum eget ante eget aliquam. Aenean sit amet diam imperdiet, lobortis diam ultricies, dapibus velit.

Morbi neque lectus, cursus in sagittis quis, sollicitudin ac elit. Aenean porta dui in euismod bibendum. Morbi lacus felis, mattis nec feugiat non, laoreet et nibh. Suspendisse mauris arcu, fringilla vitae dolor a, finibus venenatis metus. Etiam justo nunc, eleifend pretium nibh nec, euismod luctus justo. Pellentesque risus leo, congue vel metus a, gravida volutpat arcu. In iaculis sollicitudin tincidunt.

Donec ac leo id nisl malesuada viverra et id libero. Aliquam scelerisque efficitur ipsum a imperdiet. Curabitur porttitor lorem quis orci luctus, at tincidunt leo tempor. Aenean condimentum feugiat sapien, id mattis justo dignissim a. Cras quis odio a quam euismod placerat et in ex. Nulla consequat scelerisque nisl eget faucibus. Mauris eros mauris, ultricies sit amet ex accumsan, pellentesque sagittis tortor. Nam fringilla interdum quam, sed ullamcorper neque egestas id. Proin sed mattis tortor, ac auctor arcu. Cras eu neque mauris. Praesent gravida, libero eget ornare tincidunt, nibh justo consequat lorem, mattis facilisis nibh massa eu urna.</p></div>

While it may not represent the most elegant resolution, this method eliminates the need to manipulate calc() or establish specific heights using rem.

Answer №2

After conducting numerous tests, I discovered a method to achieve the desired outcome without making any changes to the HTML structure.

In order to make the grid algorithm utilize the available free space in the second row, it is necessary to use a row height specified in fractional units (fr).
I included a row with a height of 0fr in the CSS (yes, 0 fraction is valid and triggers the grid algorithm).

  • Now the red square (🟥) spans across rows 1 & 2.
  • The blue title (🟦) is located on row 1.
  • The yellow sub-title (🟨) is positioned on rows 2 & 3 (the third row being the special 0fr row).
  • And the green text (🟩) resides within row 4.

The final layout can be viewed here: https://i.sstatic.net/c8HLv.png

Below is the code snippet:

html {
    height: 100%;
}
body {
    height: 100vh;
}
.container {
    display: grid;
    grid-template-columns: 180px 1fr;
    grid-template-rows: min-content auto 0fr 1fr;
    height:100%;
}

.red-cube {
    background-color: red;
    width: 100%;
    Height: 180px;
    grid-column: 1;
    grid-row: 1 / 3;
}
h1, h2 {
    margin: 0;
    padding: 0;
}
.blue-title {
    background-color: blue;
    grid-column: 2;
    grid-row: 1;
    height: fit-content;
}
.yellow-div {
    background-color: yellow;
    grid-column: 2;
    grid-row: 2 / 4;
    height: 100%;
}
.green-content {
    background-color: green;
    grid-column: 1 / 3;
    grid-row: 4;
    align-self: stretch;
}
<div class="container">
    <div class="red-cube"></div>
    <h1 class="blue-title">Title</h1>
    <div class="yellow-div"><h2>Second line</h2></div>
    <div class="green-content"><p>Some text</p></div>
</div>

I have tested this solution on Chrome, Firefox, and Safari, all of which provided the intended result ;)

You can experiment with the Codepen version here: https://codepen.io/BSO__/pen/wvrEBWx

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

Eliminate the space between the input field and the button

I have a text field and want to place a button right next to it. Here is the code I am using: <input class="txt" type="text" name="name"> <button class="btn">Submit</button> .txt { display: inline-block; width: 80%; outline: non ...

"Troubles with directing on websites using jQuery, CSS,

I have been struggling with creating this navigation bar for weeks now and I keep running into issues. What I am attempting to achieve is a primary navigation bar that, when hovered over, displays a secondary navigation menu below and slightly to the righ ...

Styling Angular2 Material Dialog: the perfect fit

The Angular2 material team recently unveiled the MDDialog module at https://github.com/angular/material2/blob/master/src/lib/dialog/README.md I am interested in customizing the appearance of Angular2 material's dialog. Specifically, I want to adjust ...

Maintaining an element's vertical position in relation to the screen with jQuery

I'm very close to achieving what I want, but my goal is a bit unconventional. My setup includes several panels divided into 2 columns, with each panel capable of triggering an expand/compress toggle. My challenge is maintaining the vertical position ...

Animating content to slide into view in the same direction using CSS transitions

My goal is to smoothly slide one of two 'pages', represented as <divs>, into view with a gentle transition that allows the user to see one page sliding out while the other slides in. Eventually, this transition will be triggered from the ba ...

Is it possible to incorporate custom HTML tags into Jekyll?

Is it possible to have Jekyll generate template pages that preserve HTML::Template's tags for a Perl script utilizing the HTML::Template Perl module? I'd like Jekyll to ignore these tags completely. For instance: <tr> <td&g ...

Is it possible for Javascript to fetch a sound from the server once and then duplicate it across n different objects when loaded multiple times?

Incorporating Javascript into my work is crucial. Here's an example: sound = []; for (var i = 0; i < 20; i ++) sound[i] = new Audio("source.wav"); My concern is whether the sound will be retrieved from the server 20 times, or just once. I a ...

When I have a lengthy description, the alignment of the CSS DIV prices becomes misaligned

When I have a long description, the prices appear misaligned. You can take a look at it here: https://i.sstatic.net/aXgaj.jpg For the JSFiddle example, visit: https://jsfiddle.net/2n19tv75/ .border-gray { border: 1px solid #e5e7eb; float: left; w ...

Images displayed using jQuery do not fade into view

I have a collection of JSON image URLs that I am using to populate a div with a variety of images. Initially, the images are set at opacity 0 and should gradually fade in through a for loop. Here is the jQuery code snippet: $.ajax('http://example.co ...

Creating a CSS container with a uniquely shaped rounded triangle/arrow design

I would like to create a container background with a rounded arrow design. The arrow should always stretch to the full width of the container and be able to adjust its height dynamically (I can use JavaScript if needed to adjust the height). Here's a ...

How can I adjust the height of a div to fit between a fixed navbar at the top and a pinned footer at the bottom?

I am facing a challenge with a div containing a Bing map that needs to stretch to fill the entire height of the page. While I have successfully used container-fluid for the width, adjusting the height is proving tricky due to the fixed heights of the navba ...

Transforming an array into an object for generating a JavaScript report

I am trying to organize data from an array that represents a table. The array looks like this: table = [['john', 'male', 24, '12/12/12'], ['jane', 'female', 24, 12/12/12]] The goal is to allow the user t ...

Develop an XML document that includes CSS and DTD seamlessly incorporated

Could someone please provide me with a short code example of an XML file that includes both a DTD and CSS styles all in one file? Just need one element as an example. I'm new to XML and can't seem to find any examples with both XML and CSS comb ...

The jquery accordion title width does not align with the content width when an icon is included

Is there a way to adjust the widths of the heading and div elements after adding edit and delete icons to match the standard accordion style? Thanks <div id="accordion"> <h3><a href="javascript:;"> ...

Which is the preferable option for creating a circular daily planner: canvas or SVG?

As a novice programmer delving into the world of coding (or at least hoping to), I have a question regarding graphic tools in html5 for my latest project. My goal is to create a planner app using electron, with the unique twist that the planner form sho ...

"An issue was found on line 75, with column 16 reporting an error stating: AttValue expected either a double or single quote

I can't seem to figure out what's wrong with the first line: <a xlink:href=“#dccomics” xlink:title=“DC Comics”> <rect x="1023.509" y="-612.968" fill="none" stroke="#000000" stroke-width="0.5" stroke-miterlimit="10" width ...

Animate the service item with jQuery using slide toggle effect

Currently, I am working on a jQuery slide toggle functionality that involves clicking an item in one ul to toggle down the corresponding item in another ul. However, I am encountering difficulties in linking the click event to the correct id and toggling t ...

Toggle functionality not functioning correctly when clicking on two elements simultaneously

When I click on the input and the div with class "checkmark", I want the div tag with id "hidden-gift-order" to be hidden. However, clicking on the input works as expected but clicking on the div tag does not. Can someone explain why? function Toggle_Vi ...

Display a single item using Jquery when clicking on an element with the same class

I'm relatively new to JQuery/Javascript scripting and I'm having some difficulty. How can I display one item with the same class without affecting the other items? Here is my code: $(function() { $('.embedContainer > .myPosterImage& ...

Mistakes in the Horizontal Alignment of Bootstrap Forms

I'm having trouble aligning my textboxes with my form in Bootstrap within ASP.NET MVC 4. Despite using the form-horizontal div, my elements are displaying misaligned. How can I ensure that the elements align properly with the labels? <div clas ...