The stacking order of a child element within a parent element, which has a transform

Hey there, I've encountered a problem and was wondering if you could assist me with it.

In the code snippet provided below, you'll see that there are elements with:

transform: translate(0,0);

Within these elements, there is a "dropdown" element that appears upon clicking a button.

The issue arises when parts of this dropdown end up hidden behind other elements. After some investigation, I realized that this is due to the parent element having the transform property.

This is just a simplified example; my actual code is more extensive. Unfortunately, I'm unable to remove the transform property.

Is there a CSS-only solution to this dilemma? Your insights would be greatly appreciated!

Cheers!!

$(document).ready(function() {
  $('button[name="button"]').click(function(e) {
    $(e.currentTarget).parent().find('.template-options-dropdown').toggleClass('open');
  });
});
.boxes {
  list-style-type: none;
}

.boxes >li {
  float: left;
  width: 100px;
  height: 100px;
  background-color: red;
  margin: 5px;
  transform: translate(0, 0);
}

.download-container {
  background: rgba(40, 39, 39, 0.8);
  bottom: 0;
  position: absolute;
  text-align: center;
  width: 100%;
}

.download-container .dropdown-container {
  display: inline-block;
  position: relative;
}

.download-container .dropdown-container button {
  background: #0bb9ab;
  color: #fff;
  padding: 6px 12px;
}

.template-options-dropdown {
  list-style-type: none;
  text-align: left;
  padding: 0;
  position: absolute;
  background-color: #111;
  visibility: hidden;
}

.template-options-dropdown.open {
  visibility: visible;
}

.template-options-dropdown li a {
  color: white;
  text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="boxes">
  <li>
    <div class="download-container">
      <div class="dropdown-container">
        <button type="button" name="button">Download</button>

        <ul class="template-options-dropdown">
          <li>
            <a href="#">Original</a>
          </li>
          <li>
            <a href="#">Thumb</a>
          </li>
          <li>
            <a href="#">Mobile</a>
          </li>
          <li>
            <a href="#">Tab</a>
          </li>
          <li>
            <a href="#">Web</a>
          </li>
          <li>
            <a href="#">Large web</a>
          </li>
        </ul>
      </div>
    </div>
  </li>
  <li><div class="download-container">
      <div class="dropdown-container">
        <button type="button" name="button">Download</button>

        <ul class="template-options-dropdown">
          <li>
            <a href="#">Original</a>
          </li>
          <li>
            <a href="#">Thumb</a>
          </li>
          <li>
            <a href="#">Mobile</a>
          </li>
          <li>
            <a href="#">Tab</a>
          </li>
          <li>
            <a href="#">Web</a>
          </li>
          <li>
            <a href="#">Large web</a>
          </li>
        </ul>
      </div>
    </div></li>
  … (content continues)
</ul>

Answer №1

It seems that finding a CSS-only solution to this problem may be challenging due to the creation of a new stacking context by CSS3 transitions. For more information, refer to the documentation and this thread.

If a property has a non-none value, it will create a stacking context.

Source: MDN

To address this issue, you can replace translate(0,0) with position: relative and add a z-index greater than zero to .template-options-dropdown for resolution.

A somewhat unconventional approach that alters the layout is to introduce additional transforms:

  1. Invert the appearance order of the list by applying scaleY(-1) to the ul, as higher indexed list items will overlap lower ones.

  2. Add a reversing scaleY(-1) to the li elements to restore normalcy.

  3. Additionally, clear the floats on the li elements.

Check out the demonstration below:

$(document).ready(function() {
$('button[name="button"]').click(function(e) {
$(e.currentTarget).parent().find('.template-options-dropdown').toggleClass('open');
});
});
.boxes {
list-style-type: none;
transform: scaleY(-1);
}
.boxes:after {
content: '';
clear: both;
display: block;
}

.boxes >li {
float: left;
width: 100px;
height: 100px;
background-color: red;
margin: 5px;
transform: translate(0, 0) scaleY(-1);
}

.download-container {
background: rgba(40, 39, 39, 0.8);
bottom: 0;
position: absolute;
text-align: center;
width: 100%;
}

.download-container .dropdown-container {
display: inline-block;
position: relative;
}

.download-container .dropdown-container button {
background: #0bb9ab;
color: #fff;
padding: 6px 12px;
}

.template-options-dropdown {
list-style-type: none;
text-align: left;
padding: 0;
position: absolute;
background-color: #111;
visibility: hidden;
}

.template-options-dropdown.open {
visibility: visible;
}

.template-options-dropdown li a {
color: white;
text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="boxes">
<li>
<div class="download-container">
<div class="dropdown-container">
<button type="button" name="button">Download</button>

<ul class="template-options-dropdown">
<li>
<a href="#">Original</a>
</li>
<li>
<a href="#">Thumb</a>
</li>

...

</li>
</ul>
</div>
</div></li>

...

</li>
</ul>

If removing translate(0,0) proves futile, resorting to JavaScript may be necessary:

  1. Reverse the stacking order by assigning a z-index corresponding to the list index.

  2. Apply position:relative to the li elements.

Explore the demo provided below:

$(document).ready(function() {

// ADDED
$($('ul.boxes > li').get().reverse()).each(function(index){
$(this).css('z-index', index);
});

$('button[name="button"]').click(function(e) {
$(e.currentTarget).parent().find('.template-options-dropdown').toggleClass('open');
});
});
.boxes {
list-style-type: none;
}

.boxes >li {
float: left;
width: 100px;
height: 100px;
background-color: red;
margin: 5px;
transform: translate(0, 0);
position: relative;
}

.download-container {
background: rgba(40, 39, 39, 0.8);
bottom: 0;
position: absolute;
text-align: center;
width: 100%;
}

.download-container .dropdown-container {
display: inline-block;
position: relative;
}

.download-container .dropdown-container button {
background: #0bb9ab;
color: #fff;
padding: 6px 12px;
}

.template-options-dropdown {
list-style-type: none;
text-align: left;
padding: 0;
position: absolute;
background-color: #111;
visibility: hidden;
}

.template-options-dropdown.open {
visibility: visible;
}

.template-options-dropdown li a {
color: white;
text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="boxes">

...

</ul>

Answer №2

When using the <code>z-index property, remember that it will only work on elements with a position of absolute, fixed, or relative. Therefore, make sure to set the position of the element to relative.

If you have a fixed number of elements, consider assigning z-index values in the following manner:

.boxes li:nth-child(1) {
  z-index: 8;
}

.boxes li:nth-child(2) {
  z-index: 7;
}

... (continue for the rest of the elements)

Alternatively, for an unknown number of elements, you can use a script to apply z-index dynamically. Here's an example:

$(document).ready(function() {
  $('button[name="button"]').click(function(e) {
    $(e.currentTarget).parent().find('.template-options-dropdown').toggleClass('open');
  });
});
.boxes {
  list-style-type: none;
}

.boxes >li {
  float: left;
  width: 100px;
  height: 100px;
  background-color: red;
  margin: 5px;
  transform: translate(0, 0);
  position: relative;
}

.download-container {
  background: rgba(40, 39, 39, 0.8);
  bottom: 0;
  position: absolute;
  text-align: center;
  width: 100%;
}

... (continue with the CSS styles)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="boxes">
 ... (example HTML structure)
</ul>

Answer №3

You're almost there, but if it were up to me, I would apply the .open class either to the <li> element or the div.download-container. By setting a high z-index value and utilizing the cascade effect, we can reveal the sub-menu. Remember to include position:relative; on the element with the z-index property for it to take effect.

Here's an example:

$(document).ready(function() {
  $('button[name="button"]').click(function(e) {
    $(e.currentTarget).parents('li').toggleClass('open');
  });
});
.boxes {
  list-style-type: none;
}

.boxes >li {
  float: left;
  width: 100px;
  height: 100px;
  background-color: red;
  margin: 5px;
  transform: translate(0, 0);
  position:relative;
}

.boxes >li.open {
    z-index:500;
}

.download-container {
  background: rgba(40, 39, 39, 0.8);
  bottom: 0;
  position: absolute;
  text-align: center;
  width: 100%;
}

.download-container .dropdown-container {
  display: inline-block;
  position: relative;
}

.download-container .dropdown-container button {
  background: #0bb9ab;
  color: #fff;
  padding: 6px 12px;
}

.template-options-dropdown {
  list-style-type: none;
  text-align: left;
  padding: 0;
  position: absolute;
  background-color: #111;
  visibility: hidden;
}

.boxes li.open .template-options-dropdown {
  visibility: visible;
}

.template-options-dropdown li a {
  color: white;
  text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="boxes">
  <li>
    <div class="download-container">
      <div class="dropdown-container">
        <button type="button" name="button">Download</button>

        <ul class="template-options-dropdown">
          <li>
            <a href="#">Original</a>
          </li>
          <li>
            <a href="#">Thumb</a>
          </li>
          <li>
            <a href="#">Mobile</a>
          </li>
          <li>
            <a href="#">Tab</a>
          </li>
          <li>
            <a href="#">Web</a>
          </li>
          <li>
            <a href="#">Large web</a>
          </li>
        </ul>
      </div>
    </div>
  </li>

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

Implement a unique feature for specific days using jQuery UI Datepicker with a customized class

Looking to highlight a range of days horizontally in jQuery UI Datepicker with the multiselect plugin. To achieve this, I am utilizing the :before and :after pseudoelements of the a tags. .ui-state-highlight a:before, .ui-state-highlight a:after { con ...

Internet Explorer 11 features a fixed "footer" positioned at the bottom of the page. If the content above exceeds the height of the window, the footer will automatically be pushed down to accommodate

I have set up a "footer" to remain at the bottom of the page and adjust its position if the content above extends beyond the window height. While this functions correctly on Chrome, I have encountered an issue with IE11 where the footer does not adjust and ...

What is causing the qtip tooltip to show up on buttons with different ids?

I have a requirement to display tooltips only for specific buttons and not for others. I am facing an issue where the tooltip intended for the TAB button is showing up when hovering over other buttons like FOO and BAR as well. Could this be due to them sha ...

Tips for retrieving the file name from the <input type="file" tag within a JSP page

I am looking to retrieve the file path from an HTML input type="file, which is selected by the user in the file dialog. <script> function OpenFileDialog(form) { var a = document.getElementById("inputfile").click(); SampleF ...

Is it possible to maintain a div's height in proportion to its width using CSS?

Is it possible to set a CSS variable so that my div's height is always half of its width, and the width scales with the screen size (in percentage)? <div class="ss"></div> CSS: .ss { width: 30%; height: 50% of the width; } This ...

Utilizing the GROUP BY clause within an INNER JOIN operation, and presenting the results in an HTML dropdown menu

My database includes the following tables: Workers (id, total_pay, date_of_pay, projects_id) Payments (id, payment, date, projects_id) building_materials(id, pay_of_materials, date, projects_id) additional(id, add_pay, date, projects_id) All tables have p ...

Python is experiencing difficulties with copying xpath elements

I attempted to utilize some Python code to access Twitter and retrieve the "Happening now" text. Unfortunately, it was unsuccessful. import webbrowser print("Visiting Twitter.com...") webbrowser.get('C:/Program Files (x86)/Google/Chrome/Application/c ...

How can I convert the left links in my navigation bar to a CSS drop-down menu to make it more responsive on small screens?

Here is the structure of my HTML (at the top): <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></s ...

Removing the 'div' tag using jQuery in CodeIgniter

I need assistance in removing the added item. $(document).ready(function() { $("#appendex0").click(function() { $(".divcls0").append('<div class="col-sm-10 col-sm-offset-1"><div class="col-sm-3 col-sm-offset-1"><div class="form ...

Refresh the page and witness the magical transformation as the div's background-image stylish

After browsing the internet, I came across a JavaScript script that claims to change the background-image of a div every time the page refreshes. Surprisingly, it's not functioning as expected. If anyone can provide assistance, I would greatly appreci ...

Revamping Footer Text

Hey there, I'm feeling a bit inexperienced with this question, so after struggling on my own for a while I decided to turn to stackoverflow for help. So, I have a website located at , and at the very bottom of the page there's some copyright inf ...

The Issue with Non-Functional Links in Nivo Slider

Currently facing an issue with the Nivo Slider as it no longer links to any of the photos in the slider. Initially, I had 14 pictures linked to a post with a full embedded gallery inside. The problem arose when using a "fixed" size for the gallery, which d ...

I am encountering an issue while running npm run webpack in production mode where the CSS file is not being generated separately in the dist folder as expected. The file is not appearing as it should

Here is the code snippet from my webpack configuration file: const currentTask = process.env.nmp_lifecycle_event const path = require("path") const MiniCssExtractPlugin = require('mini-css-extract-plugin') const config = { entry: './ ...

Combining cells through the utilization of JavaScript

I've searched for ways to merge cells in a table using JavaScript but haven't been able to find any code that works. Is there a specific approach I can follow to implement cell merging like in MS-WORD tables? Your advice would be greatly apprec ...

Guide to parsing the HTML structure of a webpage from a different domain

Struggling with parsing the DOM of a remote webpage using AJAX. Can't find any examples or tutorials on this process. My goal is to navigate through the DOM of a remote page, locate a tag with a specific id/class, extract the content within that tag, ...

The lower section of the scrollbar is not visible

Whenever the vertical scroll bar appears on my website, the bottom half of it seems to be missing. For a live demonstration, you can visit the site HERE (navigate to the "FURTHER READING" tab). HTML: <!DOCTYPE html> <html lang="en"> <h ...

Discovering back-to-back days

I am currently working on a PHP script that utilizes a MySQL database to calculate various climatological parameters based on different variables. While I have successfully completed most of the calculations, there is one particular task that I am struggli ...

Combining HTML with multiple .ts files in Angular

I've been dedicating time to enhancing an Angular application, particularly a sophisticated table with intricate styling and functionality. Within my component file, there is a whopping 2k lines of code that includes functions for text formatting, ta ...

Attempting to eliminate an HTML element using JavaScript

Currently, I am working on creating an image rotator in JavaScript. The CSS fade animation I have applied only seems to work during element creation, so I am forced to remove the element on each loop iteration. The main issue I am encountering is related ...

I want the navigation bar to appear only upon scrolling, but when I refresh the page it is already visible, and then vanishes as I start scrolling

I'm working on a project where I want the navigation bar to only appear after scrolling a certain distance down the page. However, I've noticed that when I refresh the browser, the navigation bar appears immediately and then disappears once I sta ...