How can I correctly add a shadow and a gradient to

2020-02-26 04:40发布

I want to make the following design:

Sample image

I tried with :after and :before but it does not work. Here’s my current code:

.design {
  background: #ea053a;
  display: inline-block;
  height: 155px;
  margin-left: 33px;
  margin-right: 40px;
  position: relative;
  width: 228px;
}

.design:before {
  border-top: 43px solid #ea053a;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  margin-right: 40px;
  content: "";
  height: 0;
  left: 0;
  position: absolute;
  top: 55px;
  margin-top: 100px;
  width: 128px;
}
<div class="design"></div>

(fiddle)

How could I leave it the same as the original design and with the following two properties?:

box-shadow: 0 1px 10px 0 rgba(0, 0, 0, 0.2);
background-image: linear-gradient(to bottom, #ea053a, #d0021b);

5条回答
欢心
2楼-- · 2020-02-26 05:08

Here is my solution to add shadow and gradient to the shape

.design {
  background: #ea053a;
  display: inline-block;
  height: 155px;
  margin-left: 33px;
  margin-right: 40px;
  position: relative;
  width: 228px;
  filter: drop-shadow(0 1px 10px rgba(0, 0, 0, 0.8));
 
}

.triangle {
  position: absolute;
  height: 100px;
  top: 155px;
  width: 228px;
  -webkit-clip-path: polygon(49% 44%, 0% 100%, 100% 100%);
  clip-path: polygon(49% 44%, 0% 100%, 100% 100%);
  background-color: #ea053a;
  transform: rotate(180deg);
  
}
<div class="design">
  <div class="triangle">
  </div>
</div>

查看更多
forever°为你锁心
3楼-- · 2020-02-26 05:24

You can use clip-path as I did. Here is my solution.

.design {
  background: #ea053a;
  -webkit-clip-path: polygon(50% 0%, 100% 0, 100% 75%, 50% 100%, 0% 75%, 0 0);
  clip-path: polygon(50% 0%, 100% 0, 100% 75%, 50% 100%, 0% 75%, 0 0);
  height: 155px;
  width: 155px;
}

.month {
  text-align:center;
  padding: 1rem 0 .25rem 0;
  color:#fff;
  font-weight:bold;
  font-size: 18px;
}

.day {
  text-align: center;
  font-size: 60px;
  font-weight:bold;
  color: #fff;
}
<div class="design">
  <div class="month">Diciembre</div>
  <div class="day">29</div>
</div>

查看更多
家丑人穷心不美
4楼-- · 2020-02-26 05:28

Here is an idea with skew transformation and drop-shadow filter. You simply need some extra element to correctly have the gradient. The trick is to invert the skew to keep the gradient direction correct (not needed if we deal with solid color)

.box {
  width: 150px;
  height: 150px;
  position: relative;
  z-index:0;
  overflow: hidden;
  filter: drop-shadow(0 1px 10px rgba(0, 0, 0, 0.8));
}

.box span {
  position: absolute;
  z-index:-1;
  top: 0;
  width: 50%;
  height: 100%;
  overflow: hidden;
}

.box span:first-of-type {
  left: 0;
  transform: skewY(35deg);
  transform-origin: top right;
}

.box span:last-of-type {
  right: 0;
  transform: skewY(-35deg);
  transform-origin: top left;
}

.box span::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(to bottom, blue , red );
  transform-origin: inherit;
}

.box span:first-of-type::before {
  transform: skewY(-35deg);
}

.box span:last-of-type::before {
  transform: skewY(35deg);
}

p {
 margin:0;
 color:#fff;
 font-size:45px;
 line-height:100px;
 text-align:center;
}
<div class="box">
  <span></span><span></span>
  <p>29</p>
</div>

CSS triangle linear gradient and shadow

Here is how we can do with a left or right gradient. In this case we don't need extra elements because the skew will not affect the direction:

.box {
  width: 150px;
  height: 150px;
  position: relative;
  z-index:0;
  overflow: hidden;
  filter: drop-shadow(0 1px 10px rgba(0, 0, 0, 0.8));
}

.box:before,
.box:after{
  content:"";
  position: absolute;
  z-index:-1;
  top: 0;
  width: 50%;
  height: 100%;
  overflow: hidden;
  background:linear-gradient(to right,blue,red);
  background-size:200% 100%;
}

.box:before{
  left: 0;
  transform: skewY(35deg);
  transform-origin: top right;
}

.box:after{
  right: 0;
  transform: skewY(-35deg);
  transform-origin: top left;
  background-position:right;
}

p {
 margin:0;
 color:#fff;
 font-size:45px;
 line-height:100px;
 text-align:center;
}
<div class="box">
  <p>29</p>
</div>

And here is with an arbitrary gradient:

.box {
   --g:linear-gradient(45deg,blue,red 60%,yellow); /* gradient coloration*/

  width: 150px;
  height: 150px;
  margin:15px;
  display:inline-block;
  position: relative;
  z-index:0;
  overflow: hidden;
  filter: drop-shadow(0 1px 10px rgba(0, 0, 0, 0.8));
}

.box span {
  position: absolute;
  z-index:-1;
  top: 0;
  width: 50%;
  height: 100%;
  overflow: hidden;
}

.box span:first-of-type {
  left: 0;
  transform: skewY(35deg);
  transform-origin: top right;
}

.box span:last-of-type {
  right: 0;
  transform: skewY(-35deg);
  transform-origin: top left;
}

.box span::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--g);
  background-size:200% 100%;
  transform-origin: inherit;
}

.box span:first-of-type::before {
  transform: skewY(-35deg);
}

.box span:last-of-type::before {
  transform: skewY(35deg);
  background-position:right;
}

p {
 margin:0;
 color:#fff;
 font-size:45px;
 line-height:100px;
 text-align:center;
}
<div class="box">
  <span></span><span></span>
  <p>29</p>
</div>

<div class="box" style="--g:linear-gradient(-62deg,blue,red 60%,yellow)">
  <span></span><span></span>
  <p>29</p>
</div>

CSS gradient and drop shadow

Since each element is taking 50% of the width we make the background to be 200% to have its size as the main container then we adjust the position to create the illusion of one background. It's like each element will show half of the main background.


An optimized version using mask

.box {
  width: 150px;
  height: 150px;
  filter: drop-shadow(0 1px 10px rgba(0, 0, 0, 0.8));
}
.box > div {
  height: 100%;
  background: linear-gradient(35deg, blue, red);
  -webkit-mask: 
    linear-gradient(#fff, #fff) top/100% 70%, 
    linear-gradient(to bottom right, #fff 49.5%, transparent 50%) bottom right/50% 30%, 
    linear-gradient(to bottom left,  #fff 49.5%, transparent 50%) bottom left /50% 30%;
  mask: 
    linear-gradient(#fff, #fff) top/100% 70%, 
    linear-gradient(to bottom right, #fff 49.5%, transparent 50%) bottom right/50% 30%, 
    linear-gradient(to bottom left,  #fff 49.5%, transparent 50%) bottom left /50% 30%;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}
p {
  margin: 0;
  color: #fff;
  font-size: 45px;
  line-height: 100px;
  text-align: center;
}
<div class="box">
  <div>
    <p>29</p>
  </div>
</div>

Or clip-path

.box {
  width: 150px;
  height: 150px;
  filter: drop-shadow(0 1px 10px rgba(0, 0, 0, 0.8));
}
.box > div {
  height: 100%;
  background: linear-gradient(35deg, blue, red);
  clip-path:polygon(0 0,100% 0,100% 70%,50% 100%,0 70%);
}
p {
  margin: 0;
  color: #fff;
  font-size: 45px;
  line-height: 100px;
  text-align: center;
}
<div class="box">
  <div>
    <p>29</p>
  </div>
</div>

查看更多
【Aperson】
5楼-- · 2020-02-26 05:28

Change to (only changed lines listed, keep everything else as-is):

.design:before {
  ...
  border-left: 114px solid transparent;
  border-right: 114px solid transparent;
  ...
  width: 0;
}
查看更多
冷血范
6楼-- · 2020-02-26 05:30

If you change your CSS to the following minor changes, then you can achieve the result that you have expected:

.design {
  background: #ea053a;
  display: inline-block;
  height: 100px;
  margin-left: 33px;
  margin-right: 40px;
  position: relative;
  width: 180px;
}

.design:before {
  border-top: 43px solid #ea053a;
  border-left: 90px solid transparent;
  border-right: 90px solid transparent;
  margin-right: 40px;
  content: "";
  height: 0;
  left: 0;
  position: absolute;
  top: 0px;
  margin-top: 100px;
  width: 0;
}

Here is the working of the above CSS:

.design {
  background: #ea053a;
  display: inline-block;
  height: 100px;
  margin-left: 33px;
  margin-right: 40px;
  position: relative;
  width: 180px;
}

.design:before {
  border-top: 43px solid #ea053a;
  border-left: 90px solid transparent;
  border-right: 90px solid transparent;
  margin-right: 40px;
  content: "";
  height: 0;
  left: 0;
  position: absolute;
  top: 0px;
  margin-top: 100px;
  width: 0;
}
<div class="design">

</div>

Hope this was helpful.

My Fiddle

查看更多
登录 后发表回答