How can I ensure that only the tbody section of a table with changing column widths scrolls vertically?

On one of my pages, I have a table with dynamic width columns. Currently, the entire table scrolls horizontally if a column's width increases and causes overflow. However, I only want the body of the table to scroll vertically on overflow while keeping the header visible. The current implementation scrolls the entire table vertically.

Here is an example code snippet with dummy data mimicking my structure (jsfiddle link):

th,
td {
  text-align: left;
  padding: 5px;
  outline: solid 0.5px;
}

table {
  table-layout: auto;
  width: 100%;
  white-space: nowrap;
  overflow-x: scroll;
  overflow-y: scroll;
  height: 100px;
  display: block;
}

.container {
  width: 300px;
}
<div class="container">
  <table>
    <thead>
      <tr>
        <th>Title 1</th>
        <th>Name</th>
        <th>Address</th>
        <th>Col4</th>
        <th>Col5</th>
        <th>Col6</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Title 2</td>
        <td>Jane Doe</td>
        <td>dfss</td>
        <td>sdffsffsfd</td>
        <td>sfsfs</td>
        <td>sfsff</td>
      </tr>
      <tr>
        <td>Title 3</td>
        <td>John Doe</td>
        <td>sasas</td>
        <td>eeeee</td>
        <td>eEe</td>
        <td>sfff</td>
      </tr>
      <tr>
        <td>Title 4 is a long title</td>
        <td>Name1</td>
        <td>dfss</td>
        <td>sdffsffsfd</td>
        <td>sfsfs</td>
        <td>sfsff</td>
      </tr>
      <tr>
        <td>Title 5 is shorter</td>
        <td>Name 2</td>
        <td>dfsf</td>
        <td>sdfsf</td>
        <td>dfsf</td>
        <td>sdfsf</td>
      </tr>
      <tr>
        <td>Title 6</td>
        <td>Name 3</td>
        <td>sasas</td>
        <td>eeeee</td>
        <td>eEe</td>
        <td>sfff</td>
      </tr>
    </tbody>
  </table>
</div>

I've explored various solutions on Stack Overflow but they all set fixed widths for columns and wrap content if it exceeds the width. The only solution that didn't completely disrupt my page was table with fixed thead and scrollable tbody, however, it resulted in different column widths for header and body columns.

All other solutions either use fixed column widths or rely on JavaScript/jQuery, which I prefer not to use unless absolutely necessary. Can anyone suggest an alternative approach?

Answer №1

Not entirely sure if this addresses your query.

In cases where the y axis should always be scrollable, and the x axis only scrolls when there is excess data:

CSS

   overflow-x:auto;
   overflow-y:scroll;

Answer №2

If you need the <tbody> to be scrollable, you can use the following CSS:

tbody{
  display: block;
  height: 200px;
  width: 100%;
  overflow-y: auto;
}

To keep the <thead> fixed while the body scrolls, add this CSS:

thead tr {
  display: block;
}

Answer №3

Encountering the same issue, I devised a different solution than the one provided by @Abe Caymo

An Alternative Approach (by Abe)

Abe's approach hits a roadblock when utilizing thead and tfoot. Adding these elements disrupts the synchronization of column widths across tbody, thead, and tfoot. Refer to the demo below...

th,
td {
  text-align: left;
  padding: 5px;
  outline: solid 0.5px;
}

table {
  white-space: nowrap;
  display: block;
}

tbody{
  display: block;
  height: 100px;
  overflow-y: auto;
}
<div class="container">
  <table>
    <thead>
      <tr>
        <th>Title 1</th>
        <th>Name</th>
        <th>Address</th>
        <th>Col4</th>
        <th>Col5</th>
        <th>Col6</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Title 2</td>
        <td>Jane Doe</td>
        <td>dfss</td>
        <td>sdffsffsfd</td>
        <td>sfsfs</td>
        <td>sfsff</td>
      </tr>
    </tbody;>
  </table>
</div>

Enhanced Solution

A more effective strategy that maintains the responsive table layout is to apply position: sticky to both thead and tfoot.

There are a few considerations and nuances related to this method:

  • The scrolling element is actually the div container enclosing the table. This container determines the table's size and appearance. Hence, the scrollbar will always match the full height of the scrollable table.
  • To prevent rows in tbody from appearing behind the header while scrolling, set the background-color to an opaque value.
  • Getting the borders/outlines right may require some tweaking, but achieving a compatible style is feasible. Note that applying borders or outlines to thead or tfoot will not be "sticky".

.container {
  height: 140px;
  min-height: 100px;
  overflow: auto;
  resize: vertical; /* solely for demonstration */
}

thead,
tfoot {
  background-color: white; /* essential to prevent transparency issues */
  position: sticky;
}

thead {
  margin-bottom: 0;
  top: 0;
}

tfoot {
  margin-top: 0;
  bottom: 0;
}

th,
td {
  text-align: left;
  padding: 5px;
  outline: solid black 0.5px;
}

table {
  width: 100%;
}
<div class="container">
  <table>
    <thead>
      <tr>
        <th>Title 1</th>
        <th>Name</th>
        <th>Address</th>
        <th>Col4</th>
        <th>Col5</th>
        <th>Col6</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Title 2</td>
        <td>Jane Doe</td>
        <td>dfss</td>
        <td>sdffsffsfd</td>
        <td>sfsfs</td>
        <td>sfsff</td>
      </tr>
    </tbody;>
  </table>
</div>

The end outcome will showcase consistent alignment of all columns as demonstrated below...

https://i.sstatic.net/wSoQl.gif


For another perspective, explore this technique leveraging display: grid on the table element.

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

Is it possible for a CSS code to be universally effective across all PHP files by setting style.css in header.php and then including header.php in each of the other PHP files?

Let me confirm, the code snippet from the header.php file is as follows: <link rel="stylesheet" href="style.css"> If I include the following code in every other php file: include 'header.php'; Will all the files have access to style.css ...

Discovering the HTML5 Cache status through the utilization of Selenium's JavaScriptExecutor

How can I use Selenium's JavaScriptExecutor to retrieve HTML5 Cache status? I attempted the following code, but was unable to obtain the accurate status. import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import or ...

What is preventing the inner box from stretching to match the width of the outer box?

This question isn't really related to academics, it's more of a work-related inquiry that I've simplified into a basic question. I placed one div inside another expecting the inner div to inherit the width of the outer div. Initially, this ...

Turning off FavIcon.ico Can Enhance Performance

element: Currently, I have two websites being hosted on AEM or cq5 with distinct domains. Both websites share the same favicon on the new domain. I have attempted to remove this in the head.jsp template, but the favicon continues to display. Despite remo ...

What are the benefits of utilizing the useStyles MaterialUI function instead of traditional CSS?

As I develop my MERN application, I am utilizing Material UI components along with inline attributes. However, I find myself questioning the necessity of creating a JavaScript file just to import the makeStyles function, which essentially outputs an obje ...

Error CS0115: there is no appropriate method available to override for 'ASP.default_aspx.GetTypeHashCode()'

I'm a newcomer to the world of .Net and I'm looking to create a button that will redirect from one page to another. Here's the C# code I'm working with: using System; using System.Collections.Generic; using System.Linq; using System.We ...

What could be causing the alignment issue with cells in Bootstrap?

I'm currently facing an issue with Bootstrap where two columns that are supposed to appear side-by-side on medium resolution end up displaying one below the other. You can view a screenshot of the problem here, and the code can be found at this link. ...

Ways to distinguish between popovers using identifiers or classes

I'm encountering an issue where I have two popovers, each containing HTML content. Below is the code snippet: <button class="count" data-toggle="popover">+click me</button> <div class="popover_content_wrapper" style="display: none"&g ...

Utilize Ajax to open and close an HTML tag within separate div elements

I am facing a challenge in my project where I have to dynamically open and close a form using ajax. The form needs to be opened within a div, and then closed in another div below it like the following: Opening form (header div) $('#header').h ...

Issue encountered after updating to version 2.0 of Datatables.net: Conflict between custom CSS and BS5

Having utilized Datatables.net v1.13.11 in conjunction with custom BS5 templates from Themesbrand (), I recently upgraded to v2.0 and came across the following observations: A border box appeared when hovering over a column header. Extra top and bottom bo ...

Exploring Vaadin 14 Slider Components

I'm looking for help on how to incorporate a slider into my Vaadin 14 project. I discovered that the slider component was removed in Vaadin 10, so I turned to this alternative: Once I added the Maven dependency and repository to my pom.xml, I success ...

Is it possible to ensure that an <a href stays at the top of the page with jQuery

I have implemented the supersized plugin to display a rotating fullscreen image background that includes <a> tags. However, since it is positioned behind my site content, the images cannot be clicked. I am curious if there is a way to bring an < ...

What is preventing this Node JS code from successfully serving a static PNG file?

To the administrators, I have spent hours scouring various resources for answers related to Node Js, Express, and serving static files. Despite my efforts on stackoverflow and other platforms, I have yet to find any solution that works for me. If my questi ...

Issue with error handling while using HTML5 geolocation in Chrome browser

I have a basic map that is supposed to load centered on the user's current location if they allow HTML5 geolocation. There is a fallback function in place for users who choose not to share their location, but it seems to be malfunctioning. Here is th ...

Enable vertical scrolling on a container of undetermined height

Can a vertical scroll be implemented on a container with an unknown height using flexbox? The use of max-height is not feasible, as it would limit the height to a specific number that may not work for all screen sizes. Here is a basic example of what is ...

What is the best way to conceal HTML5 dividers if there is a custom attribute present on at least 1 selected item?

In my HTML form, I have multiple checkboxes and I want to hide certain dividers only if at least one checked checkbox has a custom HTML5 attribute called "terminator". Otherwise, I want to display the dividers. To achieve this, I attempted to use the chan ...

Tips on reducing the size of a display:block

Beginner in programming. I'm having trouble with my signature design. The block in the background is sticking out on both sides. How can I adjust its size? <td> <a href="https://twitter.com/TEST" color="#252e42" class="sc-hzDkRC kpsoy ...

What causes the footer to disappear in Rails with Bootstrap?

Within my application.html.erb file, my setup is pretty standard: <html class="h-100"> !head, title, scripts, styles, stylesheets removed for this example here on stackoverflow! <body class="d-flex flex-column h-100"> <!-- Dropdown St ...

The HTML page seems to have a glitch where it does not recognize the ID's specified in the

Feeling like an HTML and CSS newbie as I encounter my first roadblock. In my attempt to code, I have both my CSS and HTML files saved in the same directory using Notepad++. However, every time I try to open the HTML file in a browser, the specified ID in ...

I am experiencing issues with resizing my image within the CSS flexbox layout

I attempted to create a flex container for my jpg file in HTML but ran into an issue. Even after adding image dimensions in CSS, the image remained the same size with no changes at all. </head> <div class="flex-container"> ...