I am using vue-slick-carousel package.
I have three main elements with which I want to interact. The first one is a picture with a character with the class slide__person
The second one is a text with the class slide__text
and a picture with a cloud with the class banner__slider-cloud
.
I need the text to overlap the cloud, and the cloud, in turn, overlaps the picture with the person.
The cloud must remain static and cannot be moved inside the slider
I want to achieve something like this.
.banner__slider-cloud {
z-index: 1;
}
.slide__text {
z-index: 2;
}
.slide__person {
z-index: 0;
}
I tried different options, interacted with the z-index
property, tried to apply the position
property, but I could not solve this problem
You can also see my code in the online sandbox codesandbox
<script>
import VueSlickCarousel from "vue-slick-carousel";
import "vue-slick-carousel/dist/vue-slick-carousel.css";
// optional style for arrows & dots
import "vue-slick-carousel/dist/vue-slick-carousel-theme.css";
export default {
name: "HelloWorld",
components: { VueSlickCarousel },
};
</script>
<template>
<div >
<main >
<div >
<VueSlickCarousel :arrows="true" :dots="true">
<div >
<div>
<img
src="https://www.wikihow.com/images/6/61/Draw-a-Cartoon-Man-Step-15.jpg"
/>
<p >
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Aliquam architecto, corporis deserunt distinctio dolor dolores
ea ex hic iste magnam nihil optio perferendis perspiciatis
</p>
</div>
</div>
<div >
<div>
<img
src="https://www.wikihow.com/images/6/61/Draw-a-Cartoon-Man-Step-15.jpg"
/>
<p >
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Aliquam architecto, corporis deserunt distinctio dolor dolores
ea ex hic iste magnam nihil optio perferendis perspiciatis
</p>
</div>
</div>
</VueSlickCarousel>
<img src="../assets/cloud.png" />
</div>
</main>
</div>
</template>
<style>
img {
max-width: 100%;
}
.slick-slide > div {
display: flex;
justify-content: center;
}
.slide {
max-width: 500px;
border: 2px solid orange;
padding: 1rem;
}
.slide .slide__text {
border: 2px solid green;
padding: 8px;
}
.banner__slider-cloud {
border: 1px solid;
max-width: 960px;
margin: auto;
position: absolute;
right: 0;
left: 0;
top: 5%;
}
</style>
img {
max-width: 100%;
}
.slick-slide>div {
display: flex;
justify-content: center;
}
.slide {
max-width: 500px;
border: 2px solid orange;
padding: 1rem;
}
.slide .slide__text {
border: 2px solid green;
padding: 8px;
}
.banner__slider-cloud {
border: 1px solid;
max-width: 960px;
margin: auto;
position: absolute;
right: 0;
left: 0;
top: 5%;
}
<div >
<main >
<div >
<div >
<div>
<img src="https://www.wikihow.com/images/6/61/Draw-a-Cartoon-Man-Step-15.jpg" />
<p >
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam architecto, corporis deserunt distinctio dolor dolores ea ex hic iste magnam nihil optio perferendis perspiciatis
</p>
</div>
</div>
<img src="https://via.placeholder.com/500" />
</div>
</main>
</div>
CodePudding user response:
z-index
only works on elements within the same stacking context
By moving the cloud image element to be a sibling of the text and person image elements, their z-indexes will cause them to overlap the way you want
<div>
<img
src="https://www.wikihow.com/images/6/61/Draw-a-Cartoon-Man-Step-15.jpg"
/>
<p >
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Aliquam architecto, corporis deserunt distinctio dolor dolores
ea ex hic iste magnam nihil optio perferendis perspiciatis
</p>
<img src="../assets/cloud.png" />
</div>
.slide .slide__person {
position: relative;
z-index: 0;
}
.slide .slide__text {
border: 2px solid green;
padding: 8px;
position: relative;
z-index: 2;
}
.banner__slider-cloud {
border: 1px solid;
max-width: 960px;
margin: auto;
position: absolute;
left: 17%;
top: 5%;
z-index: 1;
}
CodePudding user response:
Although I believe a full solution is impossible, due to the DOM manipulation that the Vue Slick Carousel library uses, there is a workaround to the z-index
limitation using transform-style: preserve-3d
.
So long as all the elements in the DOM hierarchy being manipulated have the preserve-3d
CSS attribute applied (this property is not automatically inherited), you can use transform: translateZ()
to sort elements' layering even when they are not siblings in the stacking context. See the edited snippet below.
img {
max-width: 100%;
}
/* ### Added this block ### */
.banner * {
transform-style: preserve-3d;
}
.slick-slide>div {
display: flex;
justify-content: center;
}
.slide {
max-width: 500px;
border: 2px solid orange;
padding: 1rem;
}
.slide .slide__text {
border: 2px solid green;
padding: 8px;
transform: translateZ(1px); /* ### Added this line ### */
}
.banner__slider-cloud {
border: 1px solid;
max-width: 960px;
margin: auto;
position: absolute;
right: 0;
left: 0;
top: 5%;
}
<div >
<main >
<div >
<div >
<div>
<img src="https://www.wikihow.com/images/6/61/Draw-a-Cartoon-Man-Step-15.jpg" />
<p >
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam architecto, corporis deserunt distinctio dolor dolores ea ex hic iste magnam nihil optio perferendis perspiciatis
</p>
</div>
</div>
<img src="https://via.placeholder.com/500" />
</div>
</main>
</div>