What could be causing the ::before pseudo element to display on top of the element?

According to my understanding, the ::before pseudo-element should be positioned below the element, while the ::after pseudo-element should appear above it in terms of z-index.

In this particular scenario, I am attempting to darken just the background color (not the foreground color) when hovering over a button. Despite using ::before, it still displays in front. Why is that the case? I am aware that I could resolve this by adjusting the z-index, but as per this comment, which received 6 upvotes:

I think it's better to use :before so you get the right stacking order without playing with z-index.

I would expect not to have to do so, and the order should be correct from the outset?

.parent {
  --my-color: red;  
}
button {
    color: blue;
    background-color: var(--my-color);
    padding: 8px 16px;
    position: relative;
}
button:hover {    
    background-color: transparent;
}
button:hover::before {
    display: block;
    content: "";
    position: absolute;
    top: 0; left: 0; width: 50%; height: 100%; /* width is 50% for debugging (can see whats below) */
    background-color: var(--my-color);
    filter: brightness(80%);
}
<div class="parent">
    <button type="button">CLICK ME</button>
</div>

Answer №1

When using ::before or ::after, there is no difference in terms of z-index or z-axis order. By default, both pseudo elements will appear in front of their parent element, covering it if their position is set accordingly. To layer the z-axis beyond this default behavior, a specific z-index must be utilized, along with a combination of relative and absolute positioning.

Additional information:

The code snippet below demonstrates two scenarios, one using ::before and the other using ::after, both without a defined z-index. In both cases, the pseudo element covers its parent element:

.parent {
  --my-color: red;
}

button {
  color: blue;
  background-color: var(--my-color);
  padding: 8px 16px;
  position: relative;
}

button:hover {
  background-color: transparent;
}

.parent:nth-child(1) button:hover::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: var(--my-color);
  filter: brightness(80%);
}
.parent:nth-child(2) button:hover::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: var(--my-color);
  filter: brightness(80%);
}
<div class="parent">
  <button type="button">CLICK ME</button>
</div>

<div class="parent">
  <button type="button">CLICK ME</button>
</div>

To address the question raised in a subsequent comment: Yes, a z-index is required to position the pseudo element behind the parent element.

The solution involves adding a negative z-index: -1; for the pseudo element, as shown in the modified code snippet below (either ::before or ::after can be used):

.parent {
  --my-color: red;
}

button {
  color: blue;
  background-color: var(--my-color);
  padding: 8px 16px;
  position: relative;
}

button:hover {
  background-color: transparent;
}

button:hover::before {
  content: '';
  position: absolute;
  z-index: -1;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: var(--my-color);
  filter: brightness(80%);
}
<div class="parent">
  <button type="button">CLICK ME</button>
</div>

Answer №2

One way to ensure that the pseudo element appears behind the parent element on hover is by adjusting the z-index values. Remove the z-index from the parent element (in this case, the button) and assign a z-index to the grandparent element (in this case, .parent). Additionally, apply a negative z-index to the pseudo element.

Here is the modified code:

.parent {
  --my-color: red;
  z-index: 1;
}
button {
  color: blue;
  background-color: var(--my-color);
  padding: 8px 16px;
  position: relative;
}
button:hover {
  background-color: transparent;
}
button:hover::before {
  display: block;
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 50%;
  height: 100%;
  background-color: var(--my-color);
  filter: brightness(80%);
  z-index: -1;
}
<div class="parent">
  <button type="button">CLICK ME</button>
</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

What are the steps to achieve form styling using Bootstrap?

I am trying to achieve a specific style using the Bootstrap framework. I have been able to achieve something similar to what I want, but the issue is that the save button is not aligned to the right and is not taking up the available width. There is a gap ...

Adjusting Font Size in Angular Material Design

Recently, I incorporated https://material.angularjs.org/latest/ to optimize the responsive design of my website. One key feature I am focusing on is adjusting the font size based on different screen sizes. For smaller screens, I intend to set the font siz ...

Even though my form allows submission of invalid data, my validation process remains effective and accurate

Here is the code I have written: <!doctype html> <html lang="en"> <head> <title>Testing form input</title> <style type="text/css></style> <script type="text/javascript" src="validation.js"></script> &l ...

I am having trouble with the spacing on my website, even after I have tried declaring it

I'm having trouble formatting the footer to appear at the bottom of the page. I've tried adjusting the CSS code for the .container and .footer classes, but nothing seems to work. As a newbie in website development, any helpful tips or suggestions ...

Prevent Scrolling on Body with W3 CSS

While implementing scroll body lock packages like body-scroll-lock, react-scrolllock, or tua-body-scroll-lock alongside the W3 CSS package, I have encountered an issue where the body remains unlocked even when the designated element is active or open (e. ...

I'm looking to customize my d3.js Bar Graph by changing the color of each bar individually and adding a Scale for them. How can I

I am currently working on constructing a graph that illustrates the data for the Amount of Resources utilized Per Project by creating a bar graph. I am aiming to customize the colors of the bars so that each one has its own unique color. Currently, the col ...

Animating Jquery to smoothly change opacity until it reaches 100% visibility

The script I have does several things, but the main issue lies in the last line where the opacity of the class doesn't seem to reach 100%.... $('.fa-briefcase').parent().on('click', function () { $("#colorscreen").remove(); ...

What is the best way to display images one by one from a map using a random fade effect?

I am in the process of creating a logo wall for a website. I successfully managed to display them randomly using a map, but now I want to make them appear one by one in a random order (for example: image 1, image 6, image 3, ...) and keep them visible once ...

Label the image with unique div elements that will remain attached to the image

I am attempting to tag some divs onto an image that remains in the correct position as the window size changes. My current setup is somewhat functional, but the markers only stay aligned with the image until it loses height. How can I modify my code to en ...

How can I choose an expandable element using Selenium?

I am currently facing issues while trying to select an element on a webpage using selenium. The element in question is expandable, and when clicked, it reveals other items/fields. Here is the code snippet for the element: <DIV class="section"> ...

Creating a Text Design with a Right Arrow Symbol using HTML and CSS

I am looking to create a minimalist design using bootstrap, html, and css. The design should resemble the image found at this link: https://i.sstatic.net/WIgHJ.png I have attempted the following code to achieve the design: <div class="contain ...

Add text to the forefront of video content while in fullscreen mode

Currently, I am facing an issue while trying to embed a video from YouTube. I am unable to draw anything (text, image, etc.) when the video is in fullscreen mode. Despite my attempts to use z-index, it has not been successful. My goal is to create a n ...

Ways to expand the dimensions of a Popup while including text

I am using a bootstrap modal popup that contains a Treeview control in the body. The issue arises when the node's text width exceeds the popup's width, causing the text to overflow outside of the popup. Is there a way to dynamically adjust the ...

I am utilizing the ternary operator within the map function to dynamically adjust the column width of a material table

Looking to adjust column widths based on the IDs received from the map function. Check out the code snippet: <TableRow> { tableData.header.map(header => { header.i ...

Is there a way to create a glow effect in CSS that considers the background color?

Exploring ways to create realistic-looking LEDs using HTML and CSS has been a fun challenge. Achieving a glowing effect for each LED would be simple if the color remained constant. However, I aim for the glow to dynamically adjust based on the LED's c ...

Prevent hover animation in jQuery when the div is at the top of the page

I have a specific goal in mind: When hovering over the div labeled "hey," I want a background transition to occur. However, once the div reaches the red part of the page, I do not want that hover effect to continue on the div. When you hover over my ".ok" ...

Position the image in the center of the div both horizontally and vertically

At the moment, I have a header division with two sub-divisions called header-top and header-bottom. I am attempting to position my logo in the top-header section and align it both vertically and horizontally. The logo is aligning correctly horizontally, bu ...

What steps should I follow to make a dynamic carousel card with Bootstrap that adjusts to different screen sizes

My goal was to design a Bootstrap card with an embedded 'slideshow'. The idea was to use the second page to provide more information about the content on the first page. While editing this on the web, I managed to create a satisfactory product () ...

Problem with user scalability in desktop browsers: when zooming out to 33% and lower, all CSS vanishes

Having trouble understanding why my styling disappears at 33% zoom on Chrome and even worse at 75% on IE11. <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"> <meta name="viewport" content="w ...

I'm having trouble getting the "spacing" styling attribute to work in Material UI when I attempt to space out elements within my Box component. Can anyone explain why this might be happening?

Within my React 16.10 application, I am utilizing materialUI components. Specifically, I have incorporated two buttons inside a Box element. <Box style={{ marginTop: "3rem", marginLeft: "1rem", display: "f ...