What can be done to maintain column placement when using grid-row span?

In my CSS Grid layout, I have a 3 x 3 grid setup.

Within a row, I have three items labeled A, B, and C.

I am trying to make item C span two rows using grid-row: 1 / span 2, but it's not appearing in the correct column. It's showing up in the first column instead of the third where it should be.

I want to keep item C in its original place within the HTML structure.

One solution is to explicitly set grid-column: 3 / span 1, but I prefer not to do this. I want the items to be displayed as they are in the HTML.

Is there a way to prevent this unexpected behavior?

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

h1 {
  border: 2px solid;
  padding: 0;
  margin: 0;
  font-size: 20px;
}

.a {
  grid-row: 1 / span 2;
  background: orange;
}
<div class="grid-container">
  <div>
    <h1>A</h1>
  </div>
  <div>
    <h1>B</h1>
  </div>
  <div class="a">
    <h1>C</h1>
  </div>
</div>

Answer №1

Here is an alternative solution that sheds light on the reason behind specifying a row for the other items:

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

h1 {
  border: 2px solid;
  padding: 0;
  margin: 0;
  font-size: 20px;
}

.a {
  grid-row: 1 / span 2;
  background: orange;
}

.b {
  grid-row: 1;
}
<div class="grid-container">
  <div class="b">
    <h1>A</h1>
  </div>
  <div class="b">
    <h1>B</h1>
  </div>
  <div class="a">
    <h1>C</h1>
  </div>
</div>

This behavior occurs because the more restrictive elements are positioned first, increasing the chances of the grid algorithm finding a solution.

Elements with requirements are positioned before those without requirements.

Refer to steps 2 (for a item) and 4 (for the remaining items) in this section of the specification

https://i.sstatic.net/6er5C.png

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

Answer №2

To prevent one item from getting stuck in a specific row and blocking the flow, other grid items should also be assigned a default row.

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

div {
  grid-row: 1; /* Fix to set all items on the first row */
}

h1 {
  border: 2px solid;
  padding: 0;
  margin: 0;
  font-size: 20px;
}

.a {
  grid-row: 1 / span 2;
  background: orange;
}
<div class="grid-container">
  <div>
    <h1>A</h1>
  </div>
  <div>
    <h1>B</h1>
  </div>
  <div class="a">
    <h1>C</h1>
  </div>
</div>

If you want to specify the grid column as well, use the following code snippet:

.a {
  grid-row: 1 / span 2;
  grid-column:3;
  background: orange;
}

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

h1 {
  border: 2px solid;
  padding: 0;
  margin: 0;
  font-size: 20px;
}

.a {
  grid-row: 1 / span 2;
  grid-column:3;
  background: orange;
}
<div class="grid-container">
  <div>
    <h1>A</h1>
  </div>
  <div>
    <h1>B</h1>
  </div>
  <div class="a">
    <h1>C</h1>
  </div>
</div>

Alternatively, let auto placement determine the position of the element while specifying the number of rows to span only, which is a more flexible approach and simplifies the CSS rules:

.a {
  grid-row: span 2;
  background: orange;
}

Here's an example with minimal CSS rules using the .a class for automatic placement of grid items without specifying row or column numbers:

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

h1 {
  border: 2px solid;
  padding: 0;
  margin: 0;
  font-size: 20px;
}

.a {
  grid-row: span 2;
  background: orange;
}
<div class="grid-container">
  <div>
    <h1>A</h1>
  </div>
  <div>
    <h1>B</h1>
  </div>
  <div class="a">
    <h1>C</h1>
  </div>
</div>

Answer №3

It's evident that there is a specific element in the specification that is causing this particular behavior. At this point, the exact cause is still unclear. (Update: refer to @Vals' answer for a detailed explanation.)

Nonetheless, here is a straightforward and effective solution:

Instead of:

.a {
  grid-row: 1 / span 2;
}

Try this alternative method:

.a {
  grid-row-end: span 2;
}

Referencing the specification:

9.3. Line-based Placement: the grid-row-start, grid-column-start, grid-row-end, and grid-column-end properties

The grid-row-start, grid-column-start, grid-row-end, and grid-column-end properties define a grid item's size and position within the grid by specifying the edges of its grid area in terms of lines, spans, or auto placement.

...

For instance, using grid-column-end: span 2 refers to the second grid line in the endward direction from the grid-column-start line.


Additionally, consider implementing this single rule for complete control and efficient operation:

.a {
  grid-area: 1 / 3 /  3 / 4;
}

jsFiddle

The grid-area shorthand property interprets values in the following order:

  • grid-row-start
  • grid-column-start
  • grid-row-end
  • grid-column-end

Take note of the counterclockwise direction, contrary to margin and padding conventions.

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

Implementing a delay in a CSS menu design while still ensuring compatibility with browsers that do not support JavaScript

I currently have a three-tiered menu that relies on :hover and is controlled by css alone. I am now looking to introduce a slight delay to the hovers, which means transitioning my css :hovers to a .hover class and incorporating jQuery. My concern is whet ...

What is the significance of using single quotation marks to enclose the 'raw' key in Tailwind?

While reviewing the Tailwind documentation on custom media queries, I came across an interesting option to create a fully custom breakpoint using the 'raw' key. After adding this to my configuration file, I noticed that when I saved the file, Pr ...

React Traffic Light Component: Colors Stuck After Timeout

I've been working on solving a React issue and followed a tutorial on YouTube. I'm using CodeSandbox for my project, but I'm facing a problem where the colors of the signal are not showing up and do not change after some time. I even tried u ...

What is the method for activating the on collapse event with a bootstrap navbar?

I am encountering a common issue with collapsing the navbar on smaller screens and triggering an event when the collapse button icon is clicked. Despite my efforts to find a solution, I have been unsuccessful in using the following JavaScript code: $(&apos ...

``There Seems to be an Issue with Loading Content in Tabs

Hey! I'm encountering an issue with my jquery tabs. The first tab content loads fine, but when I select another tab, the content doesn't display. Then, when I try to go back to the first tab, it doesn't load either. Here's the HTML cod ...

What is the best way to place an anchor tag with an image inside a bootstrap grid cell?

I am facing an issue with a 9-cell grid that contains images using Bootstrap columns. The grid is responsive and functions perfectly when only images are present. However, I want to make the images clickable by placing them inside anchor tags (<a>). ...

The feature to swap out the thumb of a range slider with an image is currently not

I'm attempting to design a unique range slider using CSS. <style> .slide-container { width: 300px; } .slider { -webkit-appearance: none; width: 100%; height: 5px; border-radius: 5px; background: #FFFFFF; outline: none; opacity: ...

Using JavaScript's document.write method to display HTML code, along with a variable retrieved from a Flash application

Can I ask two questions at once? Firstly, how can I achieve the following? document.write(' <div id="jwplayer"> <center> <div id='mediaplayer'></div> <script type="text/javascript"> jwplayer('mediapl ...

When the browser window is minimized, the @media CSS will wrap to the bottom line

When the browser has a standard resolution, the layout looks like this: https://i.sstatic.net/tNR6X.png However, on smaller screens, it appears like this: https://i.sstatic.net/U3RnZ.png Is there a way to adjust the positioning of these blocks using @m ...

Stop users from submitting empty forms

I'm facing an issue with my form where I want to prevent it from being submitted if the fields are blank and also highlight those blank fields. The code I currently have works when trying to submit with blank fields, but for some reason, it doesn&apos ...

Utilize Custom Field to incorporate background videos from websites like Youtube or Vimeo into your content

I've been working on implementing a video background for my website. I came up with a custom code to embed URL links from Youtube and Vimeo using "oEmbed". The process is functioning well, but I'm facing some challenges in setting the background ...

What is the best way to ensure that a child element remains fixed in place?

What's the best way to make a left side panel (grandchild) sticky in relation to the body, while allowing a navbar and main content to be scrollable? <div> <div>navbar (should scroll away)</div> <div> <div>side pa ...

Utilizing jQuery to incorporate a radio input function in a POST request

When the Index.php page button is pressed, data is sent to the Resultx.php script page, which then responds with an asynchronous call back on the same Index.php page. index.php <script> $(document).ready(function() { $("#input_form").subm ...

Tips for implementing Animation.css in Angular version 1.5.8

I have successfully added the ngAnimate dependency to my AngularJS project: var app=angular.module('testApp',['ngRoute', 'ngAnimate']); I have also included the animation classes in my animation.css file: .slide-animation.n ...

How can you employ moment.js to display the most recent update time of mongoDB/mongoose?

I am facing an issue with displaying the last date/time when any entry in my table was edited and updated using moment.js. It seems to be updating the date/time in real-time rather than only showing when a database entry was modified. How can I ensure tha ...

Dividing a pair of CSS stylesheets on a single HTML page

Currently, I am working on a HTML page that includes multiple javascripts and css files in the header section. <link href="@Url.Content("~/Content/css/main.css")" rel="stylesheet" type="text/css" /> In order to make the website mobile-friendly, I s ...

Steps for incorporating HTML templates into a Next.js 13 project

Looking for advice on converting an HTML template using Bootstrap or Tailwind CSS into a Next.js 13.4 project. I have experience with Next.js 12 but understand that the project structure has changed, removing files like _app.js and _document.js. Any tips o ...

I am experiencing issues with my images not appearing on my Laravel website despite trying various solutions found online. The images upload successfully but fail to display on the site

I'm facing an issue where the image uploads correctly but does not display. Is there something missing in my code? <div class="col-md-4"> <img class="img img-fluid img-thumbnail" src="/storage/profile_images/{{$prof ...

Differences in behavior of multiple select with track by in Angular versions above 1.4.x

I recently upgraded my product from Angular 1.2.x to 1.4.x. Since updating to angularjs 1.4.x, I've encountered an issue: What I have: I included code snippets for both angular 1.2.0 and 1.4.8. You can check out the comparison on JSFIDDLE. Explanat ...

Tips for positioning a button beside a ListItem

Is there a way to place a button next to each list item in ASP.NET? <asp:CheckBoxList ID="lstBrembo" runat="server"> <asp:ListItem Text="Popular" Value="9"></asp:ListItem> // <--- trying to add button here, but getting parse error ...