`Issue with z-index of sticky column in Bootstrap table`

I'm experiencing an issue with my code where the Bootstrap 4 Dropdown appears under the bottom column when open, even though I have assigned a position "sticky" to the first column.

Here is an example:

The CSS code snippet below shows the application of position: sticky; to the first column.

td {
  min-width: 160px;
}

th:first-child,
td:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background-color: #ff0000;
}

.table-container {
  width: 100%;
  overflow-x: scroll;
}

table {
  width: 200%;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<div class="container-fluid">
  <div class="table-container">
    <table class="table table-striped table-bordered">
      <thead>
        <tr>
          <th>Column 1</th>
          <th>Column 2</th>
          <th>Column 3</th>
          <th>Column 4</th>
          <th>Column 5</th>
          <th>Column 6</th>
          <th>Column 7</th>
          <th>Column 8</th>
          <th>Column 9</th>
          <th>Column 10</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <div class="dropdown">
              <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</button>
              <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
                <a class="dropdown-item" href="#">Action</a>
                <a class="dropdown-item" href="#">Another action</a>
                <a class="dropdown-item" href="#">Something else here</a>
              </div>
            </div>
          </td>
          <td>Row 1, Column 2</td>
          <td>Row 1, Column 3</td>
          <td>Row 1, Column 4</td>
          <td>Row 1, Column 5</td>
          <td>Row 1, Column 6</td>
          <td>Row 1, Column 7</td>
          <td>Row 1, Column 8</td>
          <td>Row 1, Column 9</td>
          <td>Row 1, Column 10</td>
        </tr>
        <tr>
          <td>
            <div class="dropdown">
              <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</button>
              <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
                <a class="dropdown-item" href="#">Action</a>
                <a class="dropdown-item" href="#">Another action</a>
                <a class="dropdown-item" href="#">Something else here</a>
              </div>
            </div>
          </td>
          <td>Row 2, Column 2</td>
          <td>Row 2 Column 3</td>
          <td>Row 2, Column 4</td>
          <td>Row 2, Column 5</td>
          <td>Row 2, Column 6</td>
          <td>Row 2, Column 7</td>
          <td>Row 2, Column 8</td>
          <td>Row 2, Column 9</td>
          <td>Row 2, Column 10</td>
        </tr>
        <tr>
          <td>
            <div class="dropdown">
              <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</button>
              <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
                <a class="dropdown-item" href="#">Action</a>
                <a class="dropdown-item" href="#">Another action</a>
                <a class="dropdown-item" href="#">Something else here</a>
              </div>
            </div>
          </td>
          <td>Row 3, Column 2</td>
          <td>Row 3, Column 3</td>
          <td>Row 3, Column 4</td>
          <td>Row 3, Column 5</td>
          <td>Row 3, Column 6</td>
          <td>Row 3, Column 7</td>
          <td>Row 3, Column 8</td>
          <td>Row 3, Column 9</td>
          <td>Row 3, Column 10</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" [email protected]</a>/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="04767878736162666464706553716d797173766e">[email protected]</a>/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>

Despite trying to increase the z-index of the drop-down, it seems to be getting ignored.

Answer №1

The alignment of sticky elements in this scenario is influenced by the fact that each element creates its own stacking context, and the z-index values are relative to elements within the same stacking context as the first-child td or th.

To address this issue, a workaround involves adjusting the z-index of the first-child td or th element when its dropdown is open. This can be achieved using the :has() pseudo-class:

:first-child:is(th, td):has(.dropdown.show) {
  z-index: 2;
}

However, since :has() is not universally supported in major browsers yet, an alternative approach with JavaScript is suggested. This approach involves detecting an open dropdown and dynamically changing the z-index based on its state:

const observer = new MutationObserver(
  (entries) =>
    entries.forEach(({ target }) => {
      target.closest(':first-child:is(th, td)').style.zIndex =
        target.classList.contains('show') ? '2' : '';
    }),
);

document
  .querySelectorAll('.dropdown')
  .forEach((dropdown) => {
    const thTdFirst = dropdown.closest(':first-child:is(th, td)');
    if (thTdFirst) {
      observer.observe(dropdown, { attributeFilter: ['class'] });
    }
  });
td {
  min-width: 160px;
}

th:first-child,
td:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background-color: #ff0000;
}

.table-container {
  width: 100%;
  overflow-x: scroll;
}

table {
  width: 200%;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<div class="container-fluid">
  <div class="table-container">
    <table class="table table-striped table-bordered">
      <thead>
        <tr>
          <th>Column 1</th>
          <th>Column 2</th>
          <th>Column 3</th>
          <th>Column 4</th>
          <th>Column 5</th>
          <th>Column 6</th>
          <th>Column 7</th>
          <th>Column 8</th>
          <th>Column 9</th>
          <th>Column 10</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <div class="dropdown">
                ...Dropdown content...
            </div>
          </td>
          <td>Row 1, Column 2</td>
              ...Other row data...
        </tr>
            ...Additional rows...
      </tbody>
    </table>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>

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

Increase ng-grid row height dynamically based on content without any external plugins or reliance on jQuery

I came across a similar question on this topic at Angular ng-grid row height However, none of the solutions provided there meet my requirements. If I use CSS to fix the issue, it impacts the page's responsiveness and disrupts ng-grid's header fu ...

Bootstrap dropdown menu fails to expand

I recently attempted to implement a hamburger menu using Bootstrap on my website. After checking and adding the necessary CSS and JS files, I encountered an issue where the menu wasn't expanding as expected. I followed the example code provided on the ...

Ways to modify the data within a column for every row in a table without relying on props in Vue.js (specifically Element-ui)

I've been stuck on this issue for quite some time now. I've created a table with 3 columns, and for the first two columns, I can easily display the contents of each row using the prop property. However, for the third column, I need to display inf ...

Dynamic binding issue causing audio event to not fire

Currently, I have an <audio> element that is playing audio. When I manually add the event listener onplay in the HTML code, it functions as expected. <audio onplay="alert('t')" .... It's working... However, when I attempt ...

Bring in a php array to populate a dataset in JavaScript

I have extracted data and organized it into an array within a .php file. Now, I am looking to visualize this data using d3 methods in another .html file. I want to import this array into the dataset for visualization purposes. Below is a snippet of the c ...

Flex wrap is causing additional space within the layout

When using flex-wrap, if there are more textBoxes than the available width in the container, they shift to the next line. This is fine, but it leaves too much space between the button and the textBox. This spacing issue can make the layout look odd. I hav ...

Restriction on the number of characters displayed in div elements

Currently facing an issue where I need to display only the first 60 characters of a text (Description for Item) that users can see. Despite trying various solutions from stackoverflow, nothing seems to be working for me. Appreciate any help. Thank you. ...

Angular's ngClass directive failed to be applied correctly

I am currently experimenting with the use of [ngClass] in Angular and it appears that it is not being applied as expected. Interestingly, [ngStyle] for similar CSS styles is working without any issues. What could I be doing wrong in this scenario? There ar ...

Guide to positioning a link on the right side of a navigation bar

I am trying to achieve a specific layout using Bootstrap. I want to align the logout button to the right-hand side and have three modules (contact us, about epm, and modules) centered on the page. Can someone guide me on how to achieve this using Bootstr ...

How can I address multiple buttons with various events using jQuery?

I am new to learning jQuery and I'm currently working on some exercises. However, I've run into an issue with two buttons in the DOM that are supposed to perform different actions. I can't seem to figure out how to assign different functions ...

Flexbox does not support sub-columns

I'm having trouble integrating these two columns along with their sub-columns. I have to resort to using this structure instead: <div class="custom_classes"> <div class="custom_classes">col1</div> <div class=&q ...

What could be causing my browser to not respond to the JavaScript function for clicking?

I have been struggling to get the images on my browser to change when I click on them. Despite my efforts, I haven't found a solution yet... I've experimented with changing the variables to ".jpg" and also tried removing them altogether. var ...

Sending parameters to ajax using a click event

I'm facing an issue with passing variables through Ajax to PHP. In a PHP file, I'm generating some divs with id and name attributes. livesrc.php echo "<div class=\"search-results\" id=\"" . $softwareArray['Sw_idn'] ...

Customizing the styling of a TextField component in ReactJS using material-ui

I am currently working with Reactjs and material-ui. I am looking to apply some custom styles to a TextField using css. Specifically, I would like to change the color of the TextField underline and label when the input is clicked. Although I know it can b ...

Displaying website backgrounds in a digital signage system on a full screen

My pharmacy is using a Raspberry Pi and Screenly-OSE for our Digital Signage solution. We showcase various ads along with the overnights using a simple Sinatra application to serve overnights. Everything works great, but there's a pesky white space th ...

Adjust the transparency level of the image's mapped area

I need help with changing the opacity of a specific area on an image map when clicked. The image has three areas, but I only want to target and change the opacity of the test2 area regardless of which area is clicked. Since my knowledge of jQuery syntax is ...

Is it necessary to define all presentational images in CSS?

Lately, I've been diving into the world of (X)HTML & CSS and have come to understand that HTML is meant for structure while CSS is used for presentation. It makes me wonder if a significant portion of images on websites are more about enhancing p ...

Incorporating timed hover effects in React applications

Take a look at the codesandbox example I'm currently working on implementing a modal that appears after a delay when hovering over a specific div. However, I've encountered some challenges. For instance, if the timeout is set to 1000ms and you h ...

Using MDBootstrap for reactjs, incorporating a modal into a table for enhanced functionality

As a newcomer to the world of React.js and Material Design Bootstrap, I am attempting to load a dataset onto a table using a mock JSON file. After some trial and error, I managed to achieve a certain level of success with this task. My goal is to include a ...

Integrate CSS and Javascript Plugins into your Ruby on Rails application

I am utilizing an HTML, CSS, and JS template to design the interface for my Rails application. Within this template, there are several plug-ins that are required in both CSS and JS formats. I have stored these plug-ins within the "/assets/plugins/" directo ...