Guidelines for arranging nested divs in a CSS grid for a flat display

When using vue.js, I create a table from an object that should have two columns. Each column is generated from the key and value of the object. Here is the equivalent HTML:

<div id="table">
  <div>
    <div>
      this is something long on the first row
    </div>
    <div>
      short 1st row
    </div>
  </div>
  <div>
    <div>
      wazaa 2nd row
    </div>
    <div>
      wazii 2nd row
    </div>
  </div>
</div>

To format these div into a 2x2 grid, I use CSS grid with the following code:

#table {
  display: grid;
  grid-template-columns: auto 1fr;
}
<div id="table">
  <div>
    <div>
      this is something long on the first row
    </div>
    <div>
      short 1st row
    </div>
  </div>
  <div>
    <div>
      wazaa 2nd row
    </div>
    <div>
      wazii 2nd row
    </div>
  </div>
</div>

However, the result does not match my expectation. The two deepest div stack on top of each other instead of aligning in the defined grid.

I want them to follow the grid behavior and align based on the column templates. How can I achieve this?

Answer №1

If you want to tackle this issue, you have the option of using display:contents. You can find more information about it here: https://caniuse.com/#feat=css-display-contents

#table {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-gap:10px;
}

#table > div {
  display: contents;
}
<div id="table">
  <div>
    <div>
      this is something long on the first row
    </div>
    <div>
      short 1st row
    </div>
  </div>
  <div>
    <div>
      wazaa 2nd row
    </div>
    <div>
      wazii 2nd row
    </div>
  </div>
</div>

Alternatively, you can also utilize the display table property as shown below:

#table {
  display: table;
}

#table > div {
  display: table-row;
}
#table > div > div {
  display: table-cell;
  padding: 5px;
}
#table > div > div:first-child {
  white-space: nowrap;
  width: 10%;
}
<div id="table">
  <div>
    <div>
      this is something long on the first row
    </div>
    <div>
      short 1st row
    </div>
  </div>
  <div>
    <div>
      wazaa 2nd row
    </div>
    <div>
      wazii 2nd row
    </div>
  </div>
</div>

Answer №2

Your content divs are not applying grid properties because they are considered out-of-scope elements.

In grid formatting, the relationship is limited to parent-child connections. A grid container always acts as the parent, while a grid item serves as the child. Elements beyond the immediate children of a grid container do not fall within the grid layout and therefore do not respond to grid properties.

In your case, the content divs are two levels removed from the grid container (#table), making them grandchildren rather than direct children. As grandchildren, they are not recognized as grid items and thus will not inherit grid properties.

For more information, visit: Grid properties not working on elements inside grid container


Although there are exceptions to this rule, they are not widely supported by browsers.

The display: contents property, explained in another answer to this post, allows an element to be treated as if it were not a containing block. However, this method currently lacks robust browser support, rendering it impractical for production use.

An alternative approach could involve using display: subgrid, which extends grid behavior to descendants of grid items. Unfortunately, this feature is not yet supported by browsers.

For further insights, check: Positioning content of grid items in primary container (subgrid feature)


If seeking a pure CSS solution, consider combining grid and flexbox techniques.

Here's a basic concept with no HTML changes required:

#table {
  display: grid;
  grid-template-columns: 1fr;
}

#table > div {
  display: flex;
}

#table > div > div {
  flex: 1;
}
<div id="table">
  <div>
    <div>
      this is something long on the first row
    </div>
    <div>
      short 1st row
    </div>
  </div>
  <div>
    <div>
      wazaa 2nd row
    </div>
    <div>
      wazii 2nd row
    </div>
  </div>
</div>

Answer №3

If you have the possibility, my suggestion would be to modify your Vue.js code in order to avoid generating the unnecessary nested div level and instead keep it simple like this:

#table {
  display: grid;
  grid-template-columns: auto 1fr;
}
#table > div { border: 1px dotted black; }
<div id="table">
  <div>
    this is something long on the first row
  </div>
  <div>
    short 1st row
  </div>
  <div>
    wazaa 2nd row
  </div>
  <div>
    wazii 2nd row
  </div>
</div>

If this approach is not feasible for you, then you can consider using JavaScript to achieve the same effect on the client side. Another option is to utilize the display:contents method mentioned by @Temani, although its browser support may be limited and produce buggy results.


If you prefer a JavaScript-based solution, you can implement the following:

(function() {
  var table = document.getElementById("table");
  var divs = [...table.childNodes]; // use ... to enumerate the items immediately
  for (var i = 0; i < divs.length; i++) {
    var div = divs[i];
    while (div.childNodes.length > 0)
      table.appendChild(div.childNodes[0]);
    div.remove();
  }
})()
#table {
  display: grid;
  grid-template-columns: auto 1fr;
}
#table > div { border: 1px dotted black }
<div id="table">
  <div>
    <div>
      this is something long on the first row
    </div>
    <div>
      short 1st row
    </div>
  </div>
  <div>
    <div>
      wazaa 2nd row
    </div>
    <div>
      wazii 2nd row
    </div>
  </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

Hide the Bootstrap slide menu with jQuery by clicking anywhere on the screen

Here is a Fiddle link: https://jsfiddle.net/r94dq2e4/ I have incorporated a slide-in menu from the left in my website using Twitter Bootstrap version 3. The menu appears when the navbar toggle button is clicked. This is the jQuery code responsible for ...

Issues with CSS hover event causing animation to fail to trigger

I have a container that contains an image holder and a text holder. I am able to set it so that when hovered over, the image scales and the same effect applies to the text. However, when attempting to set up the image holder hover to scale the image and ...

What is the best way to format a jquery .after command when working with a table that has several classes applied?

I'm attempting to generate a table in jQuery using the .after method. Below is my code snippet: $(nearestRow).after( "<table class=" + 'table responsive bordered' + "></table>" ); The issue I'm encountering is that the DOM ...

Storing the selected value from dynamically generated options in Angular using ngFor

I have a collection of items called Fixtures. Each fixture contains a group of items named FixtureParticipants. Here is my process for generating choices: <tr *ngFor="let fixture of fixtures$ | async; let i=index"> <th scope="row& ...

Guide to creating animated sections using only CSS as you scroll the webpage

I am searching for a method to add animation effects (using @keyframes, transform...) to certain elements as the user scrolls down the page. For instance: When the offset is 0: the div will have a height of 100px. When the offset is between 0 and 100: th ...

Looking to divide a single full page into four divs of equal size using Bootstrap?

When I set the height of a container to 100% and each content section inside to 25%, why isn't it working as expected? In my browser, each div appears really small and doesn't fill the full page. Can anyone help me figure out what I'm doing ...

The alignment of the HTML and CSS speech bubble is experiencing issues

I need help with CSS as I am new to it and trying to create a speech bubble. However, when the text inside the bubble is long, it overlaps the timestamp. I am currently using `display: inline-block;` in my CSS. Below are snippets of my HTML and CSS code: ...

The functionality of my website is currently experiencing difficulties when accessed through the Android UC Browser

My website, , is experiencing issues with product loading and the '+' button in the side menu not working on UC Browser. It works fine on other Android browsers like Chrome and Firefox, but I am confused as to why it is not functioning properly o ...

When utilizing the HTML select element, the <option> tag may only display the initial letter of the chosen option

Here is a snippet of my PHP code: <?php if($_POST['post'] == 'Post') { $cat = $_POST['cat']; $update = "UPDATE table SET category='$cat' WHERE id = '$id' "; $result = mys ...

What is the best way to rearrange div class layouts for mobile devices?

I'm looking to rearrange the layout for mobile. I'd like to have the title first, followed by the image, then the paragraph, and finally the button. <div class="container"> <div class="row"> <div class="col-md-6"> ...

Getting the WC_Product object within the woocommerce_after_main_content function is a simple task that can be

I've been encountering an issue with a function that I have set up to output text after the main_content action hook in WordPress. Woocommerce keeps throwing a CRITICAL Uncaught Error: Call to a member function get_id() on null in .../function.php err ...

Tips for making basic and advanced tooltip features for canvas markers

Hi there! I am currently working on creating tooltips over canvas points, specifically a simple triangle where I hope to have tooltips for each edge point. Essentially, I am looking to add 3 tooltips for the 3 points of the triangle. I have made progress b ...

Tips for adjusting the color of the sidebar in an HTML email template

My attempt at modifying the background color of my HTML email template has been focused on changing the sidebar's white color, rather than altering the background of the email body itself. This is the CSS code I have: @import url('https://fonts. ...

Is the fixed header see-through?

I have a query regarding my website design. Currently, the fixed header on my site is transparent and when I scroll down, the content overlaps the header. However, I want the header to remain above the content. Can anyone provide assistance with this issue ...

Tips for resolving table header issues and enabling vertical movement of data while simultaneously allowing both the header and data to move vertically

I need assistance with a challenge I am facing. I have created a table using HTML tags, and now I want to add a vertical scrollbar to the browser without affecting the table's header. The data in the table should move when the vertical scrollbar is us ...

What is the best way to split a jQuery tab into four equally sized divs?

I am currently working with jquery tabs and within one of the tabs, I have 4 google charts each enclosed in a separate div. My goal is to position each div in a different quadrant of the tab area (north, south, east, and west of the screen). Currently, my ...

Fluid animation using CSS for recently added elements in a scrolling list

I've been searching for a way to create a smooth animation effect when a new element is added to a scrolling list. For example, as a new element is added to the top of the list and older elements are pushed down, I want the transition to be visually ...

It appears that IE 10 is having trouble displaying modals, possibly due to a compatibility issue with jQuery 1.7.1's animate function

By visiting www.carsense.com and clicking on the login link in the top-right corner, you may notice that the curtain appears but the modal itself does not display, even though it exists: If you locate id="content1" and modify the inline opacity to 1, the ...

Troubleshooting the lack of functionality with justify-items in CSS Grid

I'm facing an issue with my CSS Grid. I am attempting to set the justify-items property to start. Despite referencing the specification and watching a tutorial where it works, the property (and related ones) are not functioning as expected. In my tex ...

Link the same CSS file with multiple HTML pages

Currently, I am in the process of creating an external CSS file specifically for my homepage. The only issue I am encountering is that while I know how to resolve this problem for one HTML page, I am uncertain about how to address it for other pages. For ...