z-index is not working with pseudo elements [duplicate] - html

This question already has answers here:
Why can't an element with a z-index value cover its child?
(5 answers)
Closed 1 year ago.
I want to add after pseudo element for div. I did this in react. When I test it in codepen, it works in codepen. But in my local machine, it is not working. I applied z-index pseudo element only in codepen, But it works. In my project, Even I applied z-index for both parent div and pseudo element, it does not help. What mistake I did? Anyone, Please guide me. Thanks in Advance.
My code is:
HTML:
<div className='cards'>
<div className='card active'>Card</div>
<div className='card'>Card</div>
<div className='card'>Card</div>
</div>
CSS:
.card {
width: 300px;
height: 200px;
background-color: #fff;
border-radius: 5px;
&.active {
position: relative;
box-shadow: 10px 10px 60px rgba(0, 0, 0, 0.1);
z-index: 10;
&::after {
position: absolute;
content: "";
top: 0;
left: 0;
width: calc(100% + 5px);
height: calc(100% + 15px);
border-radius: 5px;
background-color: #923929;
z-index: -1000;
transform: rotateZ(-2deg);
transform-origin: top left;
}
}
}
.cards {
padding: 5rem;
display: flex;
gap: 20rem;
background-color: #92392920;
}
output is
without z-index for parent div output looks like this.

If you add z-index to parent you create new stacking context
Just remove z-index from parent element
UPD
Yes. also I need to add the background for section element
.what_we_do{
background-color: #fff6f6;
padding:5rem;
}
.card {
width: 300px;
height: 200px;
background-color: #fff;
border-radius: 5px
}
.card.active {
position: relative;
box-shadow: 10px 10px 60px rgba(0, 0, 0, 0.1);
}
.card.active::after {
position: absolute;
content: "";
top: 0;
left: 0;
width: calc(100% + 5px);
height: calc(100% + 15px);
border-radius: 5px;
background-color: #923929;
z-index: -1;
transform: rotateZ(-2deg);
transform-origin: top left;
}
.cards {
padding: 5rem;
display: flex;
gap: 20rem;
background-color: #92392920;;
position: relative;
z-index: 1;
}
<section class="what_we_do">
<div class="cards">
<div class="card active">Card</div>
<div class="card">Card</div>
<div class="card">Card</div>
</div>
</section>
UPD: from comment
I want to add effects for active card i.e. brown background for active card.
.card.active{
background-color:#923929;
}

Related

Is this elmement layout possible in CSS? Overlapping shapes with transparency in a specific arrangement

I'm trying to replicate a design using CSS, a simplified example of this is below:
The pink background should be 50% opacity, however the blue offset shadow/border should be 100% opacity.
I can do the general shapes but not in a way to achieve the desired transparency.
Here is an attempt I made:
.container {
position: relative;
margin: 0 auto;
width: 600px;
height: 200px;
}
.content-wrap {
position: relative;
z-index: 1;
filter: drop-shadow(13px 15px 0 rgb(0,255,255));
width: 60%;
height: 100%;
}
.content {
clip-path: polygon(0 0, 100% 0, 70% 100%, 0% 100%);
background: rgba(255,0,255, 0.5);
height: 200px;
}
.background {
z-index: 0;
position: absolute;
top: 20px;
left: 0;
background: black;
width: 500px;
height: 90px;
margin-top: 50px;
}
<div class="container">
<div class="content-wrap">
<!-- Blue -->
<div class="content">
<!-- Pink -->
</div>
</div>
<div class="background">
<!-- Black -->
</div>
</div>
A couple of aspects are not quite right:
The drop-shadow is visible through the pink, it should just be outside of the element.
The blue should extend to the left-hand edge.
The blue is transparent when I have not assigned it to be, it seems to be related to the child element's background being transparent.
Are there any CSS masters who can figure out a way to do this? The HTML can change if needed.
a box-shadow with skew transformation can do the job here. I am using pseudo-element for the sake of the demo but you can replace them with real elements
.box {
margin: 10px 0;
display: flex;
position: relative;
}
.box::before {
content: "";
position: absolute;
inset: 30% 0;
background: black;
}
.box::after {
content: "";
height: 200px;
width: 50%;
transform-origin: top;
transform: skew(-20deg);
background: rgb(255 0 255/80%);
box-shadow: 25px 25px 0 blue;
}
body {
margin: 0
}
<div class="box">
</div>

Move backdrop filter element behind absolute positioned element

Here's the problem
* {
color: white;
}
.must-be-top {
background-color: red;
height: 200px;
width: 200px;
position: absolute;
left: 20px;
top: 20px;
z-index: 1999;
}
.v-space {
height: 10px;
}
.blur {
height: 50px;
width: 400px;
background-color: rgba(0, 0, 0, .8);
backdrop-filter: blur(10px);
}
<div class="blur">
This is the blurred container
<div class="must-be-top">This div must be on top</div>
</div>
<div class="v-space"></div>
<div class="must-be-behind blur">This div must be behind</div>
I'm looking for a workaround to make the red div go over the blurred div. I've already read about stacking order and painting order but couldn't come up with any solution. Any ideas?
UPDATE
I need the red div to be on top of any element regardless of what they are, and I'm not in control of editing them.
Why is blur a parent of must-be-top? Changing that, and applying z-index: -1; to must-be-behind will fix your problem:
* {
color: white;
}
.must-be-top {
background-color: red;
height: 200px;
width: 200px;
position: absolute;
left: 20px;
top: 20px;
}
.v-space {
height: 10px;
}
.blur {
height: 50px;
width: 400px;
background-color: rgba(0, 0, 0, .8);
-webkit-filter: blur(1px);
}
.must-be-behind {
z-index: -1; /* new line */
position: relative; /* new line */
-webkit-filter: blur(1px) /* new line */
}
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<div class="blur">This is the blurred container</div> <!-- edited line -->
<div class="must-be-top">This div must be on top</div>
<div class="v-space"></div>
<div class="must-be-behind blur">This div must be behind</div>
</body>
</html>
Add this line to your CSS and you will get what you want:
.must-be-behind {z-index:-1; position:relative;}
The reason is without any z-index defined, your .blur div will treat the second one higher than the first one. What I did is set the .must-be-behind always be behind, and to have z-index to work, we need a positioned element.
* {
color: white;
}
.must-be-top {
background-color: red;
height: 200px;
width: 200px;
position: absolute;
left: 20px;
top: 20px;
z-index: 1999;
}
.v-space {
height: 10px;
}
.blur {
height: 50px;
width: 400px;
background-color: rgba(0, 0, 0, .8);
backdrop-filter: blur(10px);
}
.must-be-behind {z-index:-1; position:relative;}
<div class="blur">
This is the blurred container
<div class="must-be-top">This div must be on top</div>
</div>
<div class="v-space"></div>
<div class="must-be-behind blur">This div must be behind</div>

CSS: image with bigger size than the parent but cut only on horizontal sides

I have simple CSS code which scale image inside of parent element.
Image when scaling itself is bigger than a parent. Now I need to cut bigger horizontal sides but the top side will be outside of the parent. For a better understanding look at an image.
In this image is a hover statement which I need to get:
IMAGE
I already tried on parent overflow: hidden but the top side will be cut too.
Like I said I need to get a hover statement like is in image preview instead of my in example code. Is there any option on how I can get it?
.home-treneri {
padding: 56px;
}
.home-treneri-container {
max-width: 1200px;
margin: 0 auto;
display: flex;
flex-flow: row wrap;
}
img {
width: 100%;
transition: all 0.3s ease-in-out;
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: 0;
}
.background {
position: relative;
background-color: rgba(0, 0, 0, 0.5);
width: 300px;
height: 285px;
}
.trener-card {
position: relative;
cursor: pointer;
}
.trener-card:hover img {
width: 110%;
}
<section class="home-treneri">
<div class="home-treneri-container">
<div class="trener-card">
<div class="background">
<img src="https://lh3.googleusercontent.com/proxy/VpiwIPSxe7FnIAm7aWS7GiB76GDhXeTjqbIst6g0dHYaXWZEyaQ6hfbUqVEuLFqZwG7lsygIjEgf1SQ338Z0djShjmotcVgw5sTQg0Ltf638227HVN7ok3UlIiaUYycmTnJ27hAB055TWk0">
</div>
</div>
</div>
</section>
Adding clip-path: inset(-50px 0 0 0); to your trener-card class will give you the desired result.
What it basically does is clipping the image. On the top you allow the image to grow up to 50px (-50px), while on the other 3 sides you are saying that the image will be clipped (0 0 0)
.home-treneri {
padding: 56px;
}
.home-treneri-container {
max-width: 1200px;
margin: 0 auto;
display: flex;
flex-flow: row wrap;
}
img {
width: 100%;
transition: all 0.3s ease-in-out;
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: 0;
}
.background {
position: relative;
background-color: rgba(0, 0, 0, 0.5);
width: 300px;
height: 285px;
}
.trener-card {
position: relative;
cursor: pointer;
clip-path: inset(-50px 0 0 0);
}
.trener-card:hover img {
width: 110%;
}
<section class="home-treneri">
<div class="home-treneri-container">
<div class="trener-card">
<div class="background">
<img src="https://lh3.googleusercontent.com/proxy/VpiwIPSxe7FnIAm7aWS7GiB76GDhXeTjqbIst6g0dHYaXWZEyaQ6hfbUqVEuLFqZwG7lsygIjEgf1SQ338Z0djShjmotcVgw5sTQg0Ltf638227HVN7ok3UlIiaUYycmTnJ27hAB055TWk0">
</div>
</div>
</div>
</section>
You should try overflow-x: hidden on parent.

Issue with z-index and transformations

This has been asked before but none of the answers seem to be working for me.
My issue is related to a lost z-index when a transformation is applied.
I have an overlay div with a defined z-index, it has a sibling with no z-index and this div contains a child with a z-index greater than the overlay. This child can be dragged around.
At some point I rotate this sibling and it's child loses the z-index.
How can I prevent this from happening?
I tried several solutions attemps like transform-style: flat; or transform-style: preserve-3d; but with no luck
This is the code
HTML
<div class="main">
<div class="some_container">
<div class="drag"></div>
</div>
</div>
<div class="overlay"></div>
<br><br><br>
<button>rotate!</button>
CSS
body {
padding: 20px
}
div {
border: 1px solid black;
width: 50px;
height: 50px;
}
.main {
border: 1px dashed blue;
padding: 15px;
}
.some_container {
position: relative;
background-color: green;
}
.overlay {
background-color: red;
position: absolute;
left: 35px;
top: 35px;
z-index: 5
}
.drag {
position: relative;
width: 30px;
height: 30px;
background-color: lime;
z-index: 10;
cursor: move;
}
.rotated {
transform: rotateZ(15deg);
}
.rotated .drag {
background-color: yellow;
transform: rotateZ(-15deg);
position: relative;
z-index: 100;
transform-style: flat;
}
JS
$(".drag").draggable();
$("button").click(function()
{
$(".some_container").addClass("rotated");
});
fiddle: https://jsfiddle.net/2zkn9dap/
The transform that you have in your .rotated class creates a new stacking context that is changing the order that the elements are layered. A great explanation with more detail can be found here: z-index is canceled by setting transform(rotate)
The best approach to solving this is to move the .drag div to be a sibling of the .overlay and .some_container div. Then update your JS to add the rotated class to the green and yellow squares so they are both rotated. Otherwise, you'll never be able to get the yellow square on top of the red one consistently, because the z-index of the parent, in this case the .some_container div takes precedence.
$("button").click(function(){
$(".green").addClass("rotated")
$(".lime").addClass("rotated").css({backgroundColor: 'yellow'});
});
body {
padding: 20px
}
div {
border: 1px solid black;
width: 50px;
height: 50px;
}
.container {
border: 1px dashed blue;
padding: 15px;
}
.green {
position: absolute;
background-color: green;
z-index: 2;
}
.red {
background-color: red;
position: absolute;
left: 35px;
top: 35px;
z-index: 3;
}
.lime {
position: absolute;
width: 30px;
height: 30px;
background-color: lime;
z-index: 4;
cursor: move;
}
.rotated {
transform: rotateZ(15deg);
}
<div class="container">
<div class="green">
</div>
<div class="lime"></div>
</div>
<div class="red"></div>
<br><br><br>
<button>rotate!</button>
<script src="http://code.jquery.com/jquery-3.3.1.js"></script>
Change the position: relative to absolute of .lime.
If you don't want to rotate the '.lime' div, then remove `.addClass("rotated") on the 4th line of the script.

How to make in CSS an overlay over an image?

I am trying to achieve something like this:
When I hover over an image, I would like to put on that image this dark color with some text and the icon.
I am stuck here. I found some tutorials but they didn't work out for this case.
Also, another issue -- every image has a different height. The width is always the same.
How can this effect be achieved?
You can achieve this with this simple CSS/HTML:
.image-container {
position: relative;
width: 200px;
height: 300px;
}
.image-container .after {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: none;
color: #FFF;
}
.image-container:hover .after {
display: block;
background: rgba(0, 0, 0, .6);
}
HTML
<div class="image-container">
<img src="http://lorempixel.com/300/200" />
<div class="after">This is some content</div>
</div>
Demo: http://jsfiddle.net/6Mt3Q/
UPD: Here is one nice final demo with some extra stylings.
.image-container {
position: relative;
display: inline-block;
}
.image-container img {display: block;}
.image-container .after {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: none;
color: #FFF;
}
.image-container:hover .after {
display: block;
background: rgba(0, 0, 0, .6);
}
.image-container .after .content {
position: absolute;
bottom: 0;
font-family: Arial;
text-align: center;
width: 100%;
box-sizing: border-box;
padding: 5px;
}
.image-container .after .zoom {
color: #DDD;
font-size: 48px;
position: absolute;
top: 50%;
left: 50%;
margin: -30px 0 0 -19px;
height: 50px;
width: 45px;
cursor: pointer;
}
.image-container .after .zoom:hover {
color: #FFF;
}
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css" rel="stylesheet"/>
<div class="image-container">
<img src="http://lorempixel.com/300/180" />
<div class="after">
<span class="content">This is some content. It can be long and span several lines.</span>
<span class="zoom">
<i class="fa fa-search"></i>
</span>
</div>
</div>
You could use a pseudo element for this, and have your image on a hover:
.image {
position: relative;
height: 300px;
width: 300px;
background: url(http://lorempixel.com/300/300);
}
.image:before {
content: "";
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
transition: all 0.8s;
opacity: 0;
background: url(http://lorempixel.com/300/200);
background-size: 100% 100%;
}
.image:hover:before {
opacity: 0.8;
}
<div class="image"></div>
Putting this answer here as it is the top result in Google.
If you want a quick and simple way:
filter: brightness(0.2);
*Not compatible with IE
A bit late for this, but this thread comes up in Google as a top result when searching for an overlay method.
You could simply use a background-blend-mode
.foo {
background-image: url(images/image1.png), url(images/image2.png);
background-color: violet;
background-blend-mode: screen multiply;
}
What this does is it takes the second image, and it blends it with the background colour by using the multiply blend mode, and then it blends the first image with the second image and the background colour by using the screen blend mode. There are 16 different blend modes that you could use to achieve any overlay.
multiply, screen, overlay, darken, lighten, color-dodge, color-burn, hard-light, soft-light, difference, exclusion, hue, saturation, color and luminosity.
.bg-img{
text-align: center;
padding: 130px 0px;
width: 100% !important;
background-size: cover !important;
background-repeat: no-repeat !important;
background: linear-gradient(0deg, rgba(0, 0, 0, 0.86), rgba(0, 0, 0, 0.86)), url(your-img-path);
}