CSS - ensure that two elements with display: table-row stay stacked on top of one another

I came across this HTML structure

.table {
  display: table;
}

.row {
  display: table-row;
}

.cell {
  display: table-cell;
  text-align: center;
  padding: 5px;
  border-right: 1px solid #ddd;
  border-bottom: 1px solid #ddd;
}

.sticky {
  position: -webkit-sticky;
  position: sticky;
  top: 0px;
  background: red;
}
<body>
  <div class="table">
    <div class="row">
      <div class="cell sticky"><span>Header Row 1</span>
      </div>
    </div>
    <div class="row">
      <div class="cell sticky"><span>Header Row 2</span>
      </div>
    </div>
    <div class="row">
      <div class="cell">Detail Row 1</div>
    </div>
    <div class="row">
      <div class="cell">Detail Row 2</div>
    </div>
    <div class="row">
      <div class="cell">Detail Row 3</div>
    </div>
  </div>
</body>

It successfully makes the second Header Row sticky, just as intended. However, I am wondering how to make both Header Rows sticky on top of each other. This way, both rows remain visible when the user scrolls the page.

Answer №1

To ensure the second sticky block behaves correctly, it is crucial to set the top property. This value should match the height of the first sticky block. Utilize the pseudo class :nth-child() to target each parent element containing a sticky block.

The height of the initial sticky block is approximately 30px.

Review the provided CSS code for further clarification on this concept.

.table {
  display: table;
}

.row {
  display: table-row;
}

.cell {
  display: table-cell;
  text-align: center;
  padding: 5px;
  border-right: 1px solid #ddd;
  border-bottom: 1px solid #ddd;
}

.sticky {
  position: -webkit-sticky;
  position: sticky;
  background: red;
}

.row:nth-child(1) .sticky {
  top: 0px;
} 

.row:nth-child(2) .sticky {
  top: 30px;
}

Answer №2

Incorporated both headers into a unified sticky row.

.table {
    display: table;
}

.row {
    display: table-row;
}

.cell {
    display: table-cell;
    text-align: center;
    padding: 5px;
    border-right: 1px solid #ddd;
    border-bottom: 1px solid #ddd;
}

.sticky1, .sticky2, sticky {
    position: -webkit-sticky;
    position: sticky;
    top: 0px;
    background: red;
}
<div class="table">
    <div class="row">
        <div class="cell sticky1"><span>Header Row 1</span>
        <div class="cell sticky2"><span>Header Row 2</span>
        </div>
    </div>
    <div class="row">
        </div>
    </div>
    <div class="row">
        <div class="cell">Detail Row 1</div>
    </div>
    <div class="row">
        <div class="cell">Detail Row 2</div>
    </div>
    <div class="row">
        <div class="cell">Detail Row 3</div>
    </div>
    <div class="row">
        <div class="cell">Detail Row 3</div>
    </div>
    <div class="row">
        <div class="cell">Detail Row 3</div>
    </div>

Answer №3

My suggestion is to take a different approach by using a table-based structure rather than a div-based structure.

table {
  text-align: left;
  position: relative;
  border-collapse: collapse; 
}
th, td {
  padding: 0.25rem;
}
tr.red th {
  background: red;
  color: white;
}
tr.green th {
  background: green;
  color: white;
}
tr.purple th {
  background: purple;
  color: white;
}
th {
  background: white;
  position: sticky;
  top: 0; /* Don't forget this, required for the stickiness */
  box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.4);
}
<table>
  <thead>
    <tr class="red">
      <th>Header Row 1</th>
      <th>Header Row 2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Header Detail 1.</td>
      <td>Header Detail 2.</td>
    </tr>
    <tr>
      <td>Header Detail 1.</td>
      <td>Header Detail 2.</td>
    </tr>
    ... (more table rows)
  </tbody>
</table>

If you still prefer using a DIV structure, here's an example:

.wrap {
  height: 80vh;
  position: relative;
  overflow: scroll;
  margin: 10em auto 20em;
  max-width: 960px;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}

.scenes {
  display: flex;
  flex-wrap: nowrap;
}

.track {
  flex: 1 0 calc(22% + 7px);
  scroll-snap-align: start;
}

... (more CSS rules)

@media (max-width: 767px) {
  .track {
    flex: 1 0 calc(50% + 7px);
  }
}
<div class="wrap">
  <div class="scenes">
    <div class="track">
      <div class="heading">Heading 1</div>
      <div class="entry">
        <h3>Lorem ipsum dolor sit amet.</h3>
      </div>
      <div class="entry">
        <h3>Lorem ipsum dolor sit amet consectetur.</h3>
      </div>
      ... (more entries)
    </div>
    ... (more tracks)
  </div>
</div>

Answer №4

In an actual table structure, the use of thead, tbody, or tfoot tags is essential for grouping multiple rows together to maintain their position. To replicate the behavior of a tbody, the table-row-group property in CSS can be utilized :

https://developer.mozilla.org/en-US/docs/Web/CSS/display

table-row-group

table-header-group

table-footer-group

These elements function similarly to HTML elements.

A possible scenario below maintains the layout of the table and focuses on handling groups of rows rather than individual rows :

.table {
  display: table;
}

/*new */
.header-row-group {
  display: table-header-group;
  font-weight:bold;
}
/* end new */
.row {
  display: table-row;
}

.cell {
  display: table-cell;
  text-align: center;
  padding: 5px;
  border-right: 1px solid #ddd;
  border-bottom: 1px solid #ddd;
}

.sticky {
  position: -webkit-sticky;
  position: sticky;
  top: 0px;
  background: red;
}
<body>
  <div class="table">
    <div class="header-row-group sticky"><!-- header row group added -->
      <div class="row">
        <div class="cell "><span>Header Row 1</span></div> <div class="cell">header Row 1</div>
      </div>
      <div class="row">
        <div class="cell "><span>Header Row 2</span></div> <div class="cell">Wider Cell on  Row 2</div>
      </div>
    </div>
    
    <div class="row">
      <div class="cell">Detail cell</div> 
      <div class="cell">Detail cell</div>
    </div>
    <!-- Additional rows with detail cells -->

  </div>
</body>

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

Triggering an event from a Nativescript application through a webview

I am currently working on transforming my HTML5 website into a Nativescript app. The idea is to enclose the website within a Webview, but I am curious if there is a method for sharing data between the Webview and the Nativescript code. This way, I could tr ...

Creating Dynamic Height for Div Based on Another Element's Height Using ReactJS and CSS

I'm attempting to set a fixed height for a div in order to enable overflow scrolling. However, I am encountering issues as I am using JavaScript within a useEffect hook to accomplish this task. The problem is inconsistent as sometimes the height is se ...

What is the best way to display the complete text or wrap a menu item in an Angular Material menu?

Is it possible to display the full text of a menu item instead of automatically converting it to ellipses or breaking the word? I've tried various CSS methods without success. Any suggestions? https://i.stack.imgur.com/3l7gE.png #html code <mat-m ...

Conceal only the anchor tag's text and include a class during the media query

In the anchor tag below, I have a text that says "Add to cart," but on mobile view, I want to change it to display the shopping cart icon (fa fa-cart). <a class="product"><?php echo $button_add_to_cart ?></a> Currently, the variable $bu ...

Issue with Material UI React: Navbar does not properly align the box to the right side

I'm facing an issue with my navbar that is supposed to align all the page options to the right. Despite using a flexbox layout and trying different alignment properties like alignSelf: end, the text only moves slightly downwards instead of aligning pr ...

External JavaScript file not executing defined function

My homepage includes a register form that should open when the register button is clicked. However, I am encountering an issue where the function responsible for opening the form from another JavaScript file is not being triggered. Here is the HTML code: ...

What's the best way to loop through each touch event property within the TouchList of a touch event using JavaScript?

I'm struggling to grasp touch events, as nothing seems to be working for me. For testing purposes, I've created a very basic page: HTML: <div id="TOUCHME"> TOUCH ME </div> <div id="OUTPUT"></div> Jav ...

The dropdown within the modal is proving elusive for Selenium to locate

I am attempting to choose a value from the dropdown menu labeled 'ddl_settpymtaction' using Selenium, but unfortunately it seems to be unable to locate it within the modal where it is located. CSS: https://i.stack.imgur.com/3YWQu.png Selenium ...

I am looking to use flexbox and Vue.js to organize my sent messages in blue on the right and received messages in yellow on the left. How can I achieve this grouping effectively?

I've successfully built a messenger system using Vue.js with a Laravel backend. My goal is to display messages from myself (Jim, the logged in user) on the right side in blue and messages from Debbie (the recipient) on the left side in yellow, similar ...

What is the best way to choose a date and time in a custom format within my React application?

I'm currently developing the front-end of my application using React. I am looking for a way to capture the date and time in the specific format shown in this image. Any suggestions or solutions would be greatly appreciated! ...

The functionality of @Output and custom events appears to be malfunctioning

I am a beginner in Angular and attempting to pass data between child and parent components. In the child component.ts file: @Output() doubleClick = new EventEmitter<string>(); onDoubleClick(nameAccount: string){ this.doubleClick.emit(nameAccoun ...

What is the best way to set up a dropdown menu in a data grid where the width matches the fields?

I am looking to optimize the layout for various screen resolutions and ensure compatibility with the latest versions of IE, Firefox, and Chrome. ...

What is the reason for the index.html file not connecting to the local .css files and .js file?

I'm currently using node.js to send an .html file that includes the following tags: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="description" content="This is my personal profile website" /> <link r ...

issue with excessive content overflow

I'm working with a div structure where the outer div has the following CSS properties: position: relative; overflow: hidden; min-heigth: 450px; Inside this outer div, there is another div with the following CSS properties: position: absolute; top: ...

What is the process of turning a picture from a menu file into a clickable link?

I have created a menu with some images included, and I want them to be clickable links. However, currently only the text on top of the images acts as a link when hovered over. I would like the entire image to be clickable, not just the text. I believe I ...

Tips for styling Pandas dataframe using IPython HTML display

Is there a way to customize the display of pandas dataframes in IPython html format? I want to achieve the following: Have numbers right justified Add commas as thousands separators for numbers Show large floats without decimal places I am aware that nu ...

Using PHPMailer in conjunction with a textarea form and HTML

Currently, I am attempting to piece together code from a PHP tutorial that demonstrates how to create a basic PHPMailer form for sending plain text emails to a mailing list. The simplicity of the form is ideal as it will be used by only a few individuals. ...

What is the best way to utilize jQuery to expand an HTML form?

For my new web application project, I am working on a feature that allows users to create messages with attached files. Check out this image for multiple HTML file inputs using jQuery: http://img39.imageshack.us/img39/4474/attachments.gif One of the func ...

Can you transform a component with inputs into plain HTML code?

Within my Vue component named component-z, I am looking to pass specific parameters when using it in my Vue's HTML. Here is an example of how I typically do this: <component-z id="component" data1="data" data2="moreData"></component-z> N ...

What is the best way to limit the size of a table?

I need help figuring out how to limit the number of entries displayed in an SQL table on a webpage to only 10 per table. Is there a way to restrict adding more than 10 items to a table? ...