GlacJAY
GlacJAY

Reputation: 169

How can I draw a iregular shape of div and apply a shadow to it?

What I want to draw is more or less like below, in which the div's size is dynamic (depend on screen size and content in it), and two circle's size is static (in px).

Is there a better way to draw this with shadow?

body {
  background: white;
}

.card {
  background: #fff;
  border-radius: 4px;
  box-shadow: 4px 4px 4px 4px red;
  width: 200px;
  height: 200px;
  margin: 20px;
  position: relative;
}

.left,
.right {
  background: #ccc;
  position: absolute;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  filter: drop-shadow(1px 0px 0px red);
  left: -10px;
  top: 50%;
}

.right {
  left: 197px;
  filter: drop-shadow(-5px 0px 1px red);
}
<div class="card">
  <div class="left"></div>
  <div class="right"></div>
</div>

Js Fiddle here

Update: below is the actual element that I want to style, in which the box-shadow is been cut by circles.

actual element(s) to be styled

Upvotes: 4

Views: 91

Answers (1)

Temani Afif
Temani Afif

Reputation: 273750

You can do it like below using radial-gradient as background:

.box {
  margin:50px;
  border-radius:10px;
  width:200px;
  height:250px;
  background:
    radial-gradient(circle 10px at left ,transparent 98%,#fff 100%) left,
    radial-gradient(circle 10px at right,transparent 98%,#fff 100%) right;
  background-size:51% 100%;
  background-repeat:no-repeat;
  filter:drop-shadow(0 0 4px red);
}
<div class="box">
</div>

Using mask if you want a random background:

.box {
  margin:50px;
  border-radius:10px;
  width:200px;
  height:250px;
  overflow:hidden;
  filter:drop-shadow(0 0 4px red);
  position:relative;
  z-index:0;
}
.box::before {
  content:"";
  position:absolute;
  z-index:-1;
  top:0;
  left:0;
  bottom:0;
  right:0;
  background:linear-gradient(60deg,lightgreen,lightblue); /* OR url() */
  -webkit-mask:
    radial-gradient(circle 10px at left ,transparent 98%,#fff 100%) left,
    radial-gradient(circle 10px at right,transparent 98%,#fff 100%) right;
  -webkit-mask-size:51% 100%;
  -webkit-mask-repeat:no-repeat;
  
}
<div class="box">
</div>

UPDATE

In order to consider dynamic content you can do like below:

.box {
  margin: 10px;
  border-radius: 10px;
  width: 200px;
  display:inline-block;
  overflow: hidden;
  filter: drop-shadow(0 0 4px red);
}

.box>div {
  position: relative;
  z-index: 0;
  padding:10px;
}
.box>div:first-child {
}

.box div::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  -webkit-mask: 
    radial-gradient(circle 10px at var(--p, bottom) left, transparent 98%, #fff 100%) left,
    radial-gradient(circle 10px at var(--p, bottom) right, transparent 98%, #fff 100%) right;
  -webkit-mask-size: 51% 100%;
  -webkit-mask-repeat: no-repeat;
  background: grey;
}

.box div:last-child::before {
  --p: top;
  border-top:2px dotted red;
}
<div class="box">
  <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla lectus leo, tincidunt at justo malesuada, consectetur sollicitudin nulla. Integer quis condimentum ipsum. Morbi hendrerit porttitor turpis, ac fringilla ipsum posuere vel. Suspendisse non interdum lorem, id iaculis augue. </div>
  <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla lectus leo, tincidunt</div>
</div>

<div class="box">
  <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla</div>
  <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla lectus leo, tincidunt</div>
</div>

<div class="box">
  <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla</div>
  <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla lectus leo, tincidunt , tincidunt at justo malesuada, consectetur sollicitudin nulla. Integer quis condimentum ipsum. Morbi hendrerit </div>
</div>

Upvotes: 4

Related Questions