3

I have a simple test based on this codepen: https://codepen.io/davidlillo/pen/wZRagx

@import url('https://fonts.googleapis.com/css?family=Pirata+One|Rubik:900');
body {
  justify-content: center;
  align-items: center;
  min-height: 25vh;
  background-color: #141E30;
  background: linear-gradient(to right, #24243e, #141E30, #0f0c29);
}

#backinblack h1 {
  text-transform: Uppercase;
  margin-bottom: .5em;
  font-family: 'Rubik', sans-serif;
  font-size: 6rem;
  color: #E4E5E6;
}

#backinblack h1 {
  position: relative;
  background: linear-gradient(to right, #24243e, #141E30, #0f0c29);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

#backinblack h1:before,
#backinblack h1:after {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: 0;
}

#backinblack h1:before {
  z-index: -1;
  text-shadow: -0.001em -0.001em 1px rgba(255, 255, 255, .15)
}

#backinblack h1:after {
  z-index: -2;
  text-shadow: 10px 10px 10px rgba(0, 0, 0, .5), 20px 20px 20px rgba(0, 0, 0, .4), 30px 30px 30px rgba(0, 0, 0, .1);
  mix-blend-mode: multiply;
}
<div id="backinblack">
  <h1 data-text="test">test</h1>
</div>

The text shadow works fine when the CSS is like this:

body {
    justify-content: center;
    align-items: center;
    min-height: 25vh;
    background-color: #141E30;
    background: linear-gradient(to right, #24243e, #141E30, #0f0c29);
}

However, if I change it to have the CSS like this:

#backinblack {
    justify-content: center;
    align-items: center;
    min-height: 25vh;
    background-color: #141E30;
    background: linear-gradient(to right, #24243e, #141E30, #0f0c29);
}

And leave the HTML like this:

<div id="backinblack">
    <h1 data-text="test">test</h1>
</div>

Then the text-shadow does not appear:

@import url('https://fonts.googleapis.com/css?family=Pirata+One|Rubik:900');
#backinblack {
  justify-content: center;
  align-items: center;
  min-height: 25vh;
  background-color: #141E30;
  background: linear-gradient(to right, #24243e, #141E30, #0f0c29);
}

#backinblack h1 {
  text-transform: Uppercase;
  margin-bottom: .5em;
  font-family: 'Rubik', sans-serif;
  font-size: 6rem;
  color: #E4E5E6;
}

#backinblack h1 {
  position: relative;
  background: linear-gradient(to right, #24243e, #141E30, #0f0c29);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

#backinblack h1:before,
#backinblack h1:after {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: 0;
}

#backinblack h1:before {
  z-index: -1;
  text-shadow: -0.001em -0.001em 1px rgba(255, 255, 255, .15)
}

#backinblack h1:after {
  z-index: -2;
  text-shadow: 10px 10px 10px rgba(0, 0, 0, .5), 20px 20px 20px rgba(0, 0, 0, .4), 30px 30px 30px rgba(0, 0, 0, .1);
  mix-blend-mode: multiply;
}
<div id="backinblack">
  <h1 data-text="test">test</h1>
</div>

I wondered why that is the case?

4532066
  • 2,042
  • 5
  • 21
  • 48

2 Answers2

4

Thats because the background from #backinblack is placed above the shadow and therefore blocking it (if you remove the background from #backinblack, you'll see, the shadow is actually there), so you'll need a z-index on your #backisblack too, which only works if you set the divs position to absolute.

Add

  position:absolute;
  z-index:-1;
  width:100%;

to your #backinblack to change this.

More on the z-index: https://www.w3schools.com/cssref/pr_pos_z-index.asp

@import url('https://fonts.googleapis.com/css?family=Pirata+One|Rubik:900');
#backinblack {
  justify-content: center;
  align-items: center;
  min-height: 25vh;
  background-color: #141E30;
  background: linear-gradient(to right, #24243e, #141E30, #0f0c29);
  position:absolute;
  z-index:-1;
  width:100%;
}

#backinblack h1 {
  text-transform: Uppercase;
  margin-bottom: .5em;
  font-family: 'Rubik', sans-serif;
  font-size: 6rem;
  color: #E4E5E6;
}

#backinblack h1 {
  position: relative;
  background: linear-gradient(to right, #24243e, #141E30, #0f0c29);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

#backinblack h1:before,
#backinblack h1:after {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: 0;
}

#backinblack h1:before {
  z-index: -1;
  text-shadow: -0.001em -0.001em 1px rgba(255, 255, 255, .15)
}

#backinblack h1:after {
  z-index: -2;
  text-shadow: 10px 10px 10px rgba(0, 0, 0, .5), 20px 20px 20px rgba(0, 0, 0, .4), 30px 30px 30px rgba(0, 0, 0, .1);
  mix-blend-mode: multiply;
}
<div id="backinblack">
  <h1 data-text="test">test</h1>
</div>
rx2347
  • 1,071
  • 1
  • 6
  • 26
1

This is happening because of the stacking context. The browser paints the elements one-on-another like a stack, based on stacking order. In your example, the body will be considered as stacking context which means any element inside body will never go behind body. that's why it's working when you use body selector.

In another example, you have used #backinblack div element which does not have its own stacking context. which means anything inside #backinblack can go behind #backinblack tag if you use negative z-index value. that's the reason the text is not visible.

To make it work, you have to add stacking context to #backinblack in the following ways.

  1. Add any position other than static and also add any z-index other than auto
  2. Add opacity less than 1

In the below example, I just used the 2nd technique just for creating stacking context and to make it work. ex. opacity: 0.999.

@import url('https://fonts.googleapis.com/css?family=Pirata+One|Rubik:900');
#backinblack {
  justify-content: center;
  align-items: center;
  min-height: 25vh;
  background-color: #141E30;
  background: linear-gradient(to right, #24243e, #141E30, #0f0c29);
  opacity: 0.999;
}

#backinblack h1 {
  text-transform: uppercase;
  margin-bottom: .5em;
  font-family: 'Rubik', sans-serif;
  font-size: 6rem;
  color: #E4E5E6;
  color: red;
}

#backinblack h1 {
  position: relative;
  background: linear-gradient(to right, #24243e, #141E30, #0f0c29);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

#backinblack h1:before,
#backinblack h1:after {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: 0;
}

#backinblack h1:before {
  z-index: -1;
  text-shadow: -0.001em -0.001em 1px rgba(255, 255, 255, .15)
}

#backinblack h1:after {
  z-index: -2;
  text-shadow: 10px 10px 10px rgba(0, 0, 0, .5), 20px 20px 20px rgba(0, 0, 0, .4), 30px 30px 30px rgba(0, 0, 0, .1);
  mix-blend-mode: multiply;
}
<div id="backinblack">
  <h1 data-text="test">test</h1>
</div>
Ravichandran
  • 1,029
  • 6
  • 11