Rearrange items in a display: contents wrapper using CSS Grid

I'm having trouble positioning descendants in a root grid while they are enclosed in a container with display: contents.

The issue I am facing is that one element is not being correctly placed within the grid:

.wrapper {
  width: 80ch;
  margin: auto;
  margin-top: 4rem;
}

p {
  margin-block-start: 0px;
}

as-question {
  --font-size: 12pt;
  --spacing: 8px;
  width: 100%;
  display: grid;
  font-size: var(--font-size, 12pt);
  gap: var(--spacing, 8px);
  grid-template-columns: [question-number-start] 10mm [question-number-end part-number-start question-content-start] 1.75rem [part-number-end part-content-start subpart-number-start] 1.75rem [subpart-number-end subpart-content-start] auto [part-content-end subpart-content-end question-content-end marks-start] 2rem [marks-end question-end];
}
as-question:before {
  grid-column: question-number-start/question-number-end;
  content: "1.";
  counter-reset: part subpart;
}
as-question .content {
  display: contents;
}
as-question > div.content > :not(as-part):not(as-subpart) {
  grid-column: question-content-start/question-content-end;
}
as-question as-marks {
  grid-column: marks-start/marks-end;
}
as-question as-part {
  display: contents;
}
as-question as-part:before {
  counter-reset: subpart;
  counter-increment: part;
  grid-column: part-number-start/part-number-end;
  content: "(" counter(part, lower-alpha) ")";
  text-align: right;
}
as-question as-part > div.content > :not(as-subpart) {
  grid-column: part-content-start/part-content-end;
}
as-question as-part as-marks {
  color: red;
}
as-question as-subpart {
  display: contents;
}
as-question as-subpart:before {
  counter-increment: subpart;
  grid-column: subpart-number-start/subpart-number-end;
  content: "(" counter(subpart, lower-roman) ")";
  text-align: right;
}
as-question as-subpart > div.content * {
  grid-column: subpart-content-start/subpart-content-end;
}
as-question as-subpart as-marks {
  color: blue;
}
<as-question>
    <div class='content'>
      <p>This is some question content</p>
      <as-part>
        <as-marks>2</as-marks>
        <div class='content'>
          <p>Part: How can I not be pushed down?</p>
          <as-subpart>
            <as-marks>1</as-marks>
            <div class='content'>
              <p>Subpart</p>
            </div>
          </as-subpart>
          <as-subpart>
            <as-marks>1</as-marks>
            <div class='content'>
              <p>Subpart</p>
            </div>
          </as-subpart>
        </div>
      </as-part>
      <as-part>
        <as-marks>6</as-marks>
        <div class='content'>
          <p>Part</p>
          <as-subpart>
            <as-marks>4</as-marks>
            <div class='content'>
              <p>Subpart</p>
            </div>
          </as-subpart>
          <as-subpart>
            <as-marks>2</as-marks>
            <div class='content'>
              <p>Subpart</p>
            </div>
          </as-subpart>
        </div>
      </as-part>
    </div>
  </as-question>

Every time I insert an

<as-marks>{number}</as-marks>
element before a <div class='content'> (which has display: contents;), the first child of
<div class="content">
gets moved to the next row (refer to the image below).

https://i.stack.imgur.com/VTAlM.png

Is there a way to ensure the first child of <div class='content'> is placed on the same line as the marks?

Although I could revert to using grids within grids within grids, this approach seemed more organized. Looking forward to the implementation of subgrid.

Codepen for testing

If you're wondering about the unconventional HTML structure, it's because I aim to utilize Prosemirror with custom NodeViews, and this is how Prosemirror structures the resulting HTML.

Answer №1

Here are a couple of key points:

1. The grid auto-placement algorithm

The

<div class="content">
element is moved to the next line because its natural placement in the grid remains unchanged.

In simpler terms, it flows naturally to the next line based on its position in the HTML code after certain elements.

Unless specified otherwise (e.g., using grid-row: 2), the grid auto-placement algorithm takes control.

2. Using grid-auto-flow: dense

To address this issue, the grid design includes a useful feature.

By applying grid-auto-flow: dense, the algorithm prioritizes filling empty spaces earlier within the grid layout.

Ensure to add this line of code to your grid container for optimal results.

Below is an updated version of your code with one modification and the compiled CSS:

.wrapper {
  width: 80ch;
  margin: auto;
  margin-top: 4rem;
}

p {
  margin-block-start: 0px;
}

as-question {
  --font-size: 12pt;
  --spacing: 8px;
  width: 100%;
  display: grid;
  font-size: var(--font-size, 12pt);
  gap: var(--spacing, 8px);
  grid-template-columns: [question-number-start] 10mm [question-number-end part-number-start question-content-start] 1.75rem [part-number-end part-content-start subpart-number-start] 1.75rem [subpart-number-end subpart-content-start] auto [part-content-end subpart-content-end question-content-end marks-start] 2rem [marks-end question-end];
  grid-auto-flow: dense; /* NEW */
}
as-question:before {
  grid-column: question-number-start/question-number-end;
  content: "1.";
  counter-reset: part subpart;
}
as-question .content {
  display: contents;
}
as-question > div.content > :not(as-part):not(as-subpart) {
  grid-column: question-content-start/question-content-end;
}
as-question as-marks {
  grid-column: marks-start/marks-end;
}
as-question as-part {
  display: contents;
}
as-question as-part:before {
  counter-reset: subpart;
  counter-increment: part;
  grid-column: part-number-start/part-number-end;
  content: "(" counter(part, lower-alpha) ")";
  text-align: right;
}
as-question as-part > div.content > :not(as-subpart) {
  grid-column: part-content-start/part-content-end;
}
as-question as-part as-marks {
  color: red;
}
as-question as-subpart {
  display: contents;
}
as-question as-subpart:before {
  counter-increment: subpart;
  grid-column: subpart-number-start/subpart-number-end;
  content: "(" counter(subpart, lower-roman) ")";
  text-align: right;
}
as-question as-subpart > div.content * {
  grid-column: subpart-content-start/subpart-content-end;
}
as-question as-subpart as-marks {
  color: blue;
}
<div class='wrapper'>
  <as-question>
    <div class='content'>
      <p>This is some question content</p>
      <as-part>
        <as-marks>2</as-marks>
        <div class='content'>
          <p>Part: How can I not be pushed down?</p>
          <as-subpart>
            <as-marks>1</as-marks>
            <div class='content'>
              <p>Subpart</p>
            </div>
          </as-subpart>
          <as-subpart>
            <as-marks>1</as-marks>
            <div class='content'>
              <p>Subpart</p>
            </div>
          </as-subpart>
        </div>
      </as-part>
      <as-part>
        <as-marks>6</as-marks>
        <div class='content'>
          <p>Part</p>
          <as-subpart>
            <as-marks>4</as-marks>
            <div class='content'>
              <p>Subpart</p>
            </div>
          </as-subpart>
          <as-subpart>
            <as-marks>2</as-marks>
            <div class='content'>
              <p>Subpart</p>
            </div>
          </as-subpart>
        </div>
      </as-part>
    </div>
  </as-question>
</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

Filtering data in a table using Jquery based on specific columns and headers

To retrieve a price value from an HTML table based on a specific column and header, follow these steps: Here is how the table is structured: The HTML code appears as follows: <input id="search_height" placeholder="height..."> <input id= ...

What is the best way to explain the concept of HTML5?

While reading a question on Stack Overflow, I came across a comment that stated: HTML5 is equal to HTML(5) + CSS3 + JavaScript. This statement truly caught me by surprise. Can it really be argued that HTML5 can be broken down into HTML(5), CSS3, and Ja ...

Is it feasible to generate a fixed lighting effect overlay with HTML and CSS?

Is it possible to incorporate a static lighting effect overlay using HTML/CSS? My project consists of an HTML5/JS app with a top navigation bar and a series of cards that are transitioned through using swipe gestures. These cards are displayed in gray ove ...

Material UI Grid List rows are displaying with an unusually large gap between them, creating a

Currently, I am utilizing Material UI in combination with Reactjs. One particular issue that I am encountering involves the Grid List Component. In my attempt to establish a grid of 1000x1000px, I have specified the height and width within the custom gridL ...

What are some ways I can make my content come alive on my website using the Tympanus examples

After spending hours searching for a way to add animation to my content, I finally found a technique that seemed promising. Despite following the same steps as outlined in the tutorial I found, I was disappointed to discover that there was no animation o ...

HTML - Selecting Different Values in One Drop Down Based on Another Drop Down

When selecting "First Year" in the initial drop-down menu, the options "Sem1" and "Sem2" should be displayed in the second drop-down menu. Similarly, when choosing "Second Year" in the first drop-down menu, the choices "Sem3" and "Sem4" should appear in th ...

Mirror Image Iframes

Currently, I have been tasked with constructing a side-by-side "frame" using HTML. The idea is that when the content in the iframe on the left is selected, it will appear in the iframe next to it on the same page. Here's some additional context: The ...

Close the ionicPopup by tapping anywhere

Currently, I have implemented an ionicPopup that automatically closes after a certain time limit. However, I am wondering if there is a way to configure it to close with a single or double tap anywhere on the screen instead. While I am aware that setting a ...

Create a log table specifically for tracking changes made to the drop-down menu

I need to create a Change log table that will track any changes made in the drop-down menu. For instance, I am working on a worksheet with a select menu called Results which includes options like Positive, Negative, Unknown. I want the system to log any ch ...

Basic Jquery CSS style requests

Can you help me troubleshoot this issue? var hover = $('<img />').attr('src', hovers[i]).css('position', 'absolute') I'm having trouble getting th ...

Eliminate the need for background video buffering

I have a piece of code that I'm using to remove all the created players for my video elements. The code works fine, but I'm facing an issue where the video keeps buffering in the background after it's changed via an ajax call success. Can yo ...

Verify Departure on External Links within Wordpress

Let me set the stage for you: We're dealing with a bank website here. So, whenever a user wants to click on an external link (could be to a Facebook page or a partner website), we need to have a notification box pop up saying "You are about to lea ...

Loading images in advance with AJAX for enhanced AJAX performance

My website is structured in a sequential manner, where page1.html leads to page2.html and so on. I am looking to preload some images from the third page onto the second page. After searching, I came across this amazing code snippet: $.ajax({ url ...

Issue with PrestaShop not displaying page content after adding jQuery

After updating to the latest version of Presta Shop, I encountered an issue. When I inserted the following code: <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"> jQuery(document).ready(function(){ ...

SwipeJS is not compatible with a JQuery-Mobile web application

I am currently attempting to integrate SwipeJS (www.swipejs.com) into my JQuery-Mobile website. <script src="bin/js/swipe.js"></script> <style> /* Swipe 2 required styles */ .swipe { overflow: hidden; ...

`inline-block elements are centered when displayed in Firefox`

I have a question regarding formatting h2 and h3 elements to display as inline-block. Below is the code snippet: <div id="content" class="content-width"> <h2 class="headline"> My Headline </h2> <h3 class="subheadline"> My S ...

KineticJS: Applying a filter to an image does not result in the image having a stroke

Working with KineticJS version 5.1.0 I encountered an issue where a KineticJS image that had a stroke lost the stroke after applying a filter to it. I have created a demo showcasing this problem, which can be viewed on JSFiddle. Here is the code snippet: ...

What is the optimal strategy for managing multilingual text in a React website?

As I develop a react website with multiple localizations, I am faced with the question of how to best store UI texts for different languages. Currently, I am contemplating two approaches: One option is to store text directly in the UI code, using an objec ...

Dragging and dropping an HTML canvas element causes its width and height to be reset to zero

I am currently developing a customizable dashboard that allows users to rearrange dashboard tiles (represented by div elements) and position them anywhere within the dashboard. HTML Structure The HTML structure is outlined in the snippet below: <div cl ...

The Nivo Slider is stealthily concealing my CSS Menu

Although this question has been previously asked, I am still unable to make it work with the solutions provided; The website in question is I have tried changing the z-index on all menu items to 99999, but they are still appearing below. <div id="sli ...