12

I'm using Angular Material Design, and I'm trying to create the paper stack effect as given in the below codepen link:

Paper Stack using CSS3

It works fine, but the moment I add Angular Material Design CSS, it breaks (there is no more paper stack UI) could you please help me fix this, the below is the link with added Material Design CSS.

Same Paper Stack code + Material Design CSS

<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/0.8.3/angular-material.min.css">
<div class="letter">
  <p>Dear Friends,</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent euismod porta tempor. Donec pulvinar turpis nec velit pellentesque quis rhoncus sapien facilisis. Mauris quis massa dui, rhoncus viverra quam. Nulla tempus, augue ut consectetur facilisis, arcu elit pellentesque arcu, sed rutrum orci turpis pulvinar augue. Donec eget arcu mauris. Vestibulum tristique consequat lacus eget laoreet. Integer sed nisl sed nibh pulvinar ornare quis nec quam. Aenean rhoncus ligula ut lectus placerat a commodo quam vulputate. In eu metus turpis.</p>

</div>

<!-- Angular Material Dependencies -->
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-aria.min.js"></script>

    <script src="https://ajax.googleapis.com/ajax/libs/angular_material/0.8.3/angular-material.min.js"></script>
Dave Alperovich
  • 32,320
  • 8
  • 79
  • 101
user237865
  • 1,250
  • 4
  • 19
  • 41
  • have you included the required prefixes? (for transform, etc) note in your pen they have used prefix-free. – jbutler483 Apr 27 '15 at 08:22
  • Thanks for the response, dint get you - could you please be a little elaborate. – user237865 Apr 27 '15 at 09:43
  • In the linked pens, they have selected a 'prefix-free' option. In order for this to work in your actual project, you will need to add in any 'missing' prefixes in order for it to work cross browser. (you have multiple prefixes required for the [transform property](http://caniuse.com/#feat=transforms2d), for example.) – jbutler483 Apr 27 '15 at 10:12
  • But isnt the same code working fine in the first pen, without material design css? – user237865 Apr 28 '15 at 04:48

3 Answers3

7

The problem seems to be that the angular-material CSS includes background: #fff for the HTML body. This, in conjuction with the z-index: -1 used in .letter:before, .letter:after in your CSS to display the paper stack under the letter is what causes your paper stack to not be displayed since it is rendered under the body.

Solution 1: If you include background: none !important; in your own CSS for the body element you can see the paper stack again (note the use of !important since the angular-material CSS is loaded after your own).

body {
  background: none !important;
  font: 14px sans-serif;
  padding: 20px;
}

body {
  background: none !important;
  font: 14px sans-serif;
  padding: 20px;
}
.letter {
  background: #fff;
  box-shadow: 0 0 10px rgba(0,0,0,0.3);
  margin: 26px auto 0;
  max-width: 550px;
  minheight: 300px;
  padding: 24px;
  position: relative;
  width: 80%;
}
.letter:before, .letter:after {
  content: "";
  height: 98%;
  position: absolute;
  width: 100%;
  z-index: -1;
}
.letter:before {
  background: #fafafa;
  box-shadow: 0 0 8px rgba(0,0,0,0.2);
  left: -5px;
  top: 4px;
  transform: rotate(-2.5deg);
}
.letter:after {
  background: #f6f6f6;
  box-shadow: 0 0 3px rgba(0,0,0,0.2);
  right: -3px;
  top: 1px;
  transform: rotate(1.4deg);
}
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/0.8.3/angular-material.min.css">
<div class="letter">
  <p>Dear Friends,</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent euismod porta tempor. Donec pulvinar turpis nec velit pellentesque quis rhoncus sapien facilisis. Mauris quis massa dui, rhoncus viverra quam. Nulla tempus, augue ut consectetur facilisis, arcu elit pellentesque arcu, sed rutrum orci turpis pulvinar augue. Donec eget arcu mauris. Vestibulum tristique consequat lacus eget laoreet. Integer sed nisl sed nibh pulvinar ornare quis nec quam. Aenean rhoncus ligula ut lectus placerat a commodo quam vulputate. In eu metus turpis.</p>
 
</div>

<!-- Angular Material Dependencies -->
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-aria.min.js"></script>

    <script src="https://ajax.googleapis.com/ajax/libs/angular_material/0.8.3/angular-material.min.js"></script>

Solution 2: You can adjust the z-index of .letter (which will also adjust the z-index of .letter:before and .letter:after) to make everything display on top of the body background. Even a z-index of 1 will do the trick.

.letter {
  z-index: 1;
} 

Unfortunately in this case .letter:before and .letter:after will be rendered over the .letter so it will appear as if the top paper of your stack is a little crooked. You can find an explanation on why this happens with a reference to the relevant part of the spec in this question. If you choose this solution however you can always make the stack appear the way you want it with a bit of manipulation of the rotations and positions of the various elements

.letter {
  z-index: 1;
  transform: rotate(1.4deg);
}
.letter p {
  transform: rotate(-1.4deg);
}
.letter:before {
  transform: rotate(-3.9deg);
}
.letter:after {
  transform: rotate(-1.4deg);
}

body {
  background: #888;
  font: 14px sans-serif;
  padding: 20px;
}
.letter {
  background: #f6f6f6;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
  margin: 26px auto 0;
  max-width: 550px;
  minheight: 300px;
  padding: 24px;
  position: relative;
  width: 80%;
  z-index: 1;
  transform: rotate(1.4deg);
}
.letter p {
  transform: rotate(-1.4deg);
}
.letter:before,
.letter:after {
  content: "";
  height: 98%;
  position: absolute;
  width: 100%;
  z-index: -1;
}
.letter:before {
  background: #fafafa;
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
  left: -5px;
  top: 4px;
  transform: rotate(-3.9deg);
}
.letter:after {
  background: #fafafa;
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);
  right: 3px;
  top: 1px;
  transform: rotate(-1.4deg);
}
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/0.8.3/angular-material.min.css">
<div class="letter">
  <p>Dear Friends,</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent euismod porta tempor. Donec pulvinar turpis nec velit pellentesque quis rhoncus sapien facilisis. Mauris quis massa dui, rhoncus viverra quam. Nulla tempus, augue ut consectetur facilisis,
    arcu elit pellentesque arcu, sed rutrum orci turpis pulvinar augue. Donec eget arcu mauris. Vestibulum tristique consequat lacus eget laoreet. Integer sed nisl sed nibh pulvinar ornare quis nec quam. Aenean rhoncus ligula ut lectus placerat a commodo
    quam vulputate. In eu metus turpis.</p>

</div>

<!-- Angular Material Dependencies -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-aria.min.js"></script>

<script src="https://ajax.googleapis.com/ajax/libs/angular_material/0.8.3/angular-material.min.js"></script>
Community
  • 1
  • 1
Christina
  • 3,562
  • 3
  • 22
  • 32
  • Thanks for the response. Can you please update the code. I tried giving background: none !important; but then you need to do that for the parent element as well - and so on. If we change z-index 1, the papers are jumbled and the text goes to the bottom - please check – user237865 May 11 '15 at 16:36
  • @user237865 I have updated my answer with code snippets where you can see both proposed solutions. – Christina May 12 '15 at 09:54
7

Christina is on the right track, but before and after are very finicky css3 behaviors.

unfortunately, setting

.letter {
z-index:1
}

will cause before and after to inherit and as they are rendered after your main div, they will be layered above. Even setting

.letter:before, .letter:after {
 z-index: -1 !important;
}

will not fix that problem.

Similarly, setting

body {
 background: none !important;
}

will not be inherited.

Imperfect Solutions

1) make the body transparent:

body {
 background: transparent !important;
}

CodePen

This has the disadvantage that you are stuck with no background color.

Setting z-index for div and p children

.letter {
    z-index: 1;
}
.letter div {
  z-index: 2;
}
.letter p {
  z-index: 3;
}

CodePen

This has the disadvantage of making the after element be at top and look like your main paper is slightly crossed.

Dave Alperovich
  • 32,320
  • 8
  • 79
  • 101
  • 1
    Thanks Dave. I think your second solutions will be good for now (though we dont need .letter div : z-index: 2). Will play around to fix the main paper straight ... – user237865 May 11 '15 at 18:56
4

The origin of the problem is that the pseudo elements on letter must have a negative z-index in order to be under letter itself.

But letter can not have a definite z-index because that will limit the efectiveness of the negative z-index. And in absence of this z-index, then the pseudo elements will be, not only under letter, but also under the ancestors of letter (body in this case).

I think that the easiest way to handle this is to make letter be a separate stacking context.

And one posibility to do that is to set a transform, for instance

.letter {
    transform: translateZ(0px);
}

codepen

stacking context reference

vals
  • 61,425
  • 11
  • 89
  • 138