4

I want to combine two shapes and their shadows, to create the UI shown below.

In my attempts the shadow of the first element would overlap the second element.

Any ideas how I can make this work, cross browser?

Shadow overlap

HTML

<div class="mainShape">
  <div class="subShape">

  </div>
</div>

CSS

.mainShape {
  position: relative;
  box-shadow: 6px 0 21px -3px rgba(86,93,111,0.12);
  background: white;
  width: 200px;
  height: 600px;
}

.subShape {
  position: absolute;
  top: 0px;
  right: -60px;
  width: 60px;
  height: 180px;
  box-shadow: 6px 0 21px -3px rgba(86,93,111,0.12);
}

https://jsfiddle.net/mk32g7yj/7/

Titsjmen
  • 789
  • 6
  • 15
  • You may want to consider using a svg as the background. Another solution would be to have a "sharp" edge dropshadow by having a solid coloured element behind it, and setting its opacity. – Sumurai8 Jun 13 '18 at 18:30

2 Answers2

3

There may be a more elegant way to do this, such as Sumurai's suggestion of using an svg, but a rather hacky way of achieving this could be to stick a "masking" div (with a white background) up between the two other divs:

.mainShape {
  position: relative;
  box-shadow: 6px 0 21px -3px rgba(86,93,111,0.12);
  background: white;
  width: 200px;
  height: 600px;
}

.subShape {
  position: absolute;
  top: 0px;
  right: -60px;
  width: 60px;
  height: 180px;
  box-shadow: 6px 0 21px -3px rgba(86,93,111,0.12);
}

.mask {
  position: absolute;
  top:0px;
  right:-20px;
  width:25px;
  height:180px;
  background-color:white;
}
<div class="mainShape">
  <div class="subShape">

  </div>
  <div class="mask">
  
  </div>
</div>
Michael Beeson
  • 2,840
  • 2
  • 17
  • 25
1

CSS box-shadow only works nicely with boxes. When you start combining them, things will get ugly. The nicest solution, I think, is to create a background using an svg. The solution below uses the dropshadow as written by Erik Dahlström.

I used a polygon in this case, but you can use any shape you could possibly create with an svg, or even an image I think. Since you hardcoded the width and height, I used hardcoded coordinates. Nothing prevents you from calculating them on the fly if you need to. Note that the svg is bigger than the element we want to provide a dropshadow for, and that I don't touch any of the corners. The reason is, obviously, because we need to draw the dropshadow. Things drawn outside the svg boundaries are not shown, so we need to make sure that we have enough wiggle room to show everything.

* {
  box-sizing: border-box;
}

.mainShape {
  position: relative;
  width: 200px;
  height: 600px;
  margin: 15px;
  background: white;
  padding: 5px;
}

.subShape {
  position: absolute;
  top: 0px;
  right: -60px;
  width: 60px;
  height: 180px;
  padding: 5px;
  background: white;
}

.background {
  position: absolute;
  z-index: -1;
  top: -10px;
  left: -10px;
  width: 280px;
  height: 620px;
}
<div class="mainShape">
  Text in main shape
  <div class="subShape">
    :-)
  </div>
  <!-- SVG drop shadow using css3: https://stackoverflow.com/a/6094674/2209007 -->
  <svg class="background">
    <filter id="dropshadow">
    <feGaussianBlur in="SourceAlpha" stdDeviation="5"/>
    <feOffset dx="2" dy="1" result="offsetblur"/>
    <feComponentTransfer>
      <feFuncA type="linear" slope="0.5"/>
    </feComponentTransfer>
    <feMerge> 
      <feMergeNode/>
      <feMergeNode in="SourceGraphic"/>
    </feMerge>
  </filter>
  <polygon points="10,10 270,10 270,190 210,190 210,610 10,610" style="filter:url(#dropshadow)"/>
  </svg>
</div>
Sumurai8
  • 20,333
  • 11
  • 66
  • 100