How to avoid shadow bleed when using positioned absolute elements?

I'm facing a challenge in developing a dropdown feature. The issue arises when I attempt to display an absolutely positioned container of items upon hovering, as the shadow from this container overlaps with the dropdown itself. Here's a simulation of the problem:

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 50px;
}

.dropdown {
  position: relative;
  width: 200px;
  height: 40px;
  box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
  background-color: #efefef;
}

.items {
  display: none;
  position: absolute;
  overflow: hidden;
  overflow-y: auto;
  width: 100%;
  height: 100px;
  top: 100%;
  box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
  background-color: #f7f7f7;
}

.dropdown:hover .items {
  display: block;
}

.item {
  padding: 5px 10px;
}
<div class="dropdown">
  <div class="items">
    <div class="item">a</div>
    <div class="item">b</div>
    <div class="item">c</div>
    <div class="item">d</div>
  </div>
</div>
<div>hello</div>

Upon hovering over the dropdown, you'll notice the top part of the shadow from the .items container obscuring the view. Here's an illustrative example of the issue:

https://i.sstatic.net/GtI3y.png

It seems like restricting the box shadow to solely the dropdown is the obvious fix, but this poses a challenge when the items container is set to position absolute, thereby not receiving the box shadow effect.

Any suggestions on how to overcome this obstacle?

Answer №1

To enhance the appearance of the dropdown menu, consider adding a :before element to the .dropdown class with a slightly smaller height than the items. Here's an example:

.dropdown:hover:before {
    position: absolute;
    content: "";
    width: 100%;
    height: 98px;
    box-shadow: rgb(0 0 0 / 24%) 0px 6px 8px;
    background: red;
    bottom: -100px;
    z-index: 0;
}

Furthermore, it is recommended to eliminate the shadow effect from the .items element for a cleaner design.

Answer №2

I believe Jackson's idea of utilizing a pseudo element is spot on.

However, I would approach it slightly differently:

.dropdown:hover::after {
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: #efefef;
}

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 50px;
}

.dropdown {
  position: relative;
  width: 200px;
  height: 40px;
  box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
  background-color: #efefef;
}

.items {
  display: none;
  position: absolute;
  overflow: hidden;
  overflow-y: auto;
  width: 100%;
  height: 100px;
  top: 100%;
  box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
  background-color: #f7f7f7;
}

.dropdown:hover .items {
  display: block;
}
.dropdown:hover::after {
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: #efefef;
}

.item {
  padding: 5px 10px;
}
<div class="dropdown">
  <div class="items">
    <div class="item">a</div>
    <div class="item">b</div>
    <div class="item">c</div>
    <div class="item">d</div>
  </div>
</div>
<div>hello</div>

Another way to approach this would be to increase the height of .dropdown on hover, and position the items list independent of .dropdown's height:

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 50px;
}

.dropdown {
  position: relative;
  width: 200px;
  height: 40px;
  box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
  background-color: #efefef;
}

.items {
  display: none;
  position: absolute;
  overflow: hidden;
  overflow-y: auto;
  width: 100%;
  height: 100px;
  top: 40px;
  box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
  background-color: #f7f7f7;
}

.dropdown:hover .items {
  display: block;
}
.dropdown:hover {
  height: 140px;
}

.item {
  padding: 5px 10px;
}
<div class="dropdown">
  <div class="items">
    <div class="item">a</div>
    <div class="item">b</div>
    <div class="item">c</div>
    <div class="item">d</div>
  </div>
</div>
<div>hello</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

Use the inline IF statement to adjust the icon class depending on the Flask variable

Is it feasible to achieve this using the inline if function? Alternatively, I could use JavaScript. While I've come across some similar posts here, the solutions provided were not exactly what I expected or were implemented in PHP. <i class="f ...

Loop through the input template using ng-repeat with various data types

I have been working on developing a user interface for adding and modifying information in a database. To manage the database, I am utilizing breeze, displaying data using angular grid, and incorporating a ui-bootstrap modal dialog for user interaction. ...

Inconsistency with Mobile Viewport Problem

Apologies for the chaos below, but I've spent quite some time attempting to fix this on my own. It's time to surrender and seek assistance! Here are some screenshots to illustrate the issue: The problem is that sometimes the webpage functions c ...

Sending a variable to a template in AngularJS

I am looking for a way to pass a variable or text to a template in order to display the value within my template. While browsing through resources, I found an example on jsFiddle that demonstrates this functionality using ng-repeat. However, I am curious ...

Issue with React-Native FlatList's scrolling functionality

Struggling with implementing a scrolling FlatList in React Native. Despite trying various solutions found on Stack Overflow, such as adjusting flex properties and wrapping elements in views, the list still refuses to scroll. Snippet of code (issue is with ...

Form in HTML - Transmit rows consecutively as an array

Hey there, I have a bit of a perplexing issue that I'm hoping to get some help with. I have a form that pulls data from my database. It displays names in one column and two columns of checkboxes. My goal is to update the database based on the checkb ...

Prevent the use of harmful language by implementing jQuery or JavaScript

Is there a way for me to filter certain words (such as "sex") using regex, even when people use variations like "b a d", "b.a.d", or "b/a/d"? How can I prevent these kinds of words from getting through? I'm trying to filter more than just one word - ...

The font-face feature is only functional in Chrome, not in Firefox or Opera

Hey there, I'm having an issue with the font-face element. It seems to work perfectly fine in Chrome, but doesn't seem to be working in any other browser. Any ideas on what could be causing this? Thanks in advance! Check out the demo here -> ...

Display flash messages consistently in a designated area on the webpage instead of appearing at the top of the page in Flask

{% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} <div class="alert alert-{{ category }}" style=" ...

Block Button styles not displaying in IE when set to Full Width

I can't figure out why, but it seems to be functioning properly on every other internet platform except this one. The first picture shows the button in IE, the second contains the code, and the third displays the button in Chrome. https://i.sstatic. ...

Python code displays output directly on an HTML webpage

I have created a basic Python chatbot that performs calculations and responds to user input. The chatbot continuously runs in Python, checking previous responses for context. I want to make this chatbot available online and achieve the following: Send us ...

What could be causing my website to lose its responsiveness after linking a domain?

Recently, I created a basic website for an event in my town using AWS Amplify from Amazon. Initially, the website was hosted without a custom domain and had a random URL. It worked well on both web and mobile platforms. However, after connecting a custom d ...

Troubleshooting problems with Flask's render_template()

I've been working on a Flask web application that requires users to be logged in to access the contents and functionalities. However, I've encountered an issue where, sometimes after logging in, instead of loading the full home page, a blank "abo ...

Ways to add a substantial quantity of HTML to the DOM without relying on AJAX or excessive strings

Currently, I am looking to update a div with a large amount of HTML content when a button on my webpage is clicked. The approach I am currently using involves the .html() method in JQuery, passing in this extensive string: '<div class="container-f ...

What could be causing my website to function flawlessly in Firefox but not in Chrome or Internet Explorer?

Hey everyone, I'm feeling lost and have been comparing files using DiffNow. I don't have any code to offer because I'm unsure of where to even begin. The website is coded in php/html/mysql/jquery. Here are my main concerns: -Animations are ...

Rearrange the li elements within multiple ul lists using JavaScript

Is there a way to reorder multiple ul-lists on my website using JavaScript? An example of the lists may be as follows: $(document).ready(function() { var ul = $('ul.filelist'); for (let u = 0; u < ul.length; u++) { const element = ul[ ...

Live PHP statement continuously updates display

Below is the setup for my input field. The question to fill in the input will only be prompted if either $client_chargeBy is equal to "Square Foot" or "Room" <div class="col-md-12 p0 "> <div class="col-md-6 PL0 p0_smresp"> <di ...

What is the best way to adjust the width of a column grid header in extjs

When adjusting the width of a vertical header in a grid to 50px, the header text disappears unless manually dragged to the left. How can I ensure the header text remains visible even with a smaller header size? Consider the following code snippet: { text ...

Adjusting the dimensions of the "overflow avatar" to be consistent with the other avatars displayed in AvatarGroup

When setting the max prop of the AvatarGroup, the additional avatar does not match the height of the other avatars. <AvatarGroup max={3}> <Avatar alt="Remy Sharp" src="/static/images/avatar/1.jpg" sx={{ width: 24, height: 24 ...

Trouble arises when trying to link IE7 with jQuery

I am currently testing a website with jQuery. There is a plugin that, when hovered over, slides down to reveal another banner, subsequently sliding the banner below it down as well. I have added a link on the bottom banner using z-index, and although it wo ...