4

For my online game UI, I decided to make Hill Climb Racing (Android Game)'s buttons. This is is what I have presently :

body {
    color: white;
    font-family: Impact, fantasy;
    font-size: 40px;
    line-height: 100px;
    text-align: center;
}
.rect {
    height: 100px;
    width: 280px;
    background: #545D60;
    border-radius: 20px 50px 50px 20px;
    position: relative;
}
.rect:before {
    background: #545D60;
    content: "";
    position: absolute;
    top: 6px;
    left: 195px;
    height: 0px;
    width: 0px;
    border-radius: 30px 10px;
    border: 44px solid #545D60;
    transform: rotate(45deg);
}
<div class="rect">NEXT</div>

enter image description here

The problem lies with aligning the gradient properly. A gradient background could be added to rect, but the same gradient doesn't align properly with the triangle on the right.
Solutions such as this one are helpful, but don't apply to what I am trying : link

Also, can we create a responsive shape with gradient background?

Note : this is not a duplicate, its a completely different question.

EDIT

Also, on hover, the gradient becomes upside down, ie rotates 180 deg. This part I can create, but aligning the gradients of rect and before is still a problem.

Community
  • 1
  • 1

1 Answers1

4

Caution: This is not quite the way you had in mind to achieve this, but in my opinion this is probably the simplest way to achieve it without resorting to SVG or images or complex angle calculations in gradients. Rotating pseudo-elements etc will cause the other side to mismatch because you have a curved side on the right.

The shape is achieved by using two pseudo-elements which are about half the size of the parent (.rect), skewing them in opposite directions and then positioning them exactly one below the other. The other skewed side (left hand side) is hidden from view by positioning it inside the parent rectangle using the left property of the pseudo-elements.

The required gradient is assigned to both the parent and the pseudo-elements. For the parent the full gradient is applied as required whereas for the pseudo-elements it is split exactly in half between the the :before and :after elements to make it look as a gradual progression.

Since the :before and :after pseudo-elements are effectively children of the main element, a hover on them effectively means an hover on the parent also.

The span contains the text and is positioned with a higher z-index for it to be above the pseudo-elements and thereby be visible.

body {
  color: white;
  font-family: Impact, fantasy;
  font-size: 40px;
  line-height: 100px;
  text-align: center;
}
.rect {
  height: 100px;
  width: 225px;
  position: relative;
  border-radius: 20px 0px 0px 20px;
  background: -webkit-gradient(linear, 0 0, 0 100%, from(#949DA0), to(#545D60));
  background: -webkit-linear-gradient(#949DA0, #545D60);
  background: -moz-linear-gradient(#949DA0, #545D60);
  background: -o-linear-gradient(#949DA0, #545D60);
  background: linear-gradient(#949DA0, #545D60);
}
.rect span {
  position: relative;
  z-index: 2;
}
.rect:before {
  background: #545D60;
  content: "";
  position: absolute;
  top: 0px;
  left: 42px;
  height: 51%;
  width: 100%;
  border-radius: 0px 10px 6px 0px;
  background: -webkit-gradient(linear, 0 0, 0 100%, from(#949DA0), to(#747D80));
  background: -webkit-linear-gradient(#949DA0, #747D80);
  background: -moz-linear-gradient(#949DA0, #747D80);
  background: -o-linear-gradient(#949DA0, #747D80);
  background: linear-gradient(#949DA0, #747D80);
  -webkit-transform: skew(45deg);
  -moz-transform: skew(45deg);
  transform: skew(45deg);
}
.rect:after {
  background: #545D60;
  content: "";
  position: absolute;
  bottom: 0px;
  left: 42px;
  height: 51%;
  width: 100%;
  border-radius: 0px 6px 10px 0px;
  background: -webkit-gradient(linear, 0 0, 0 100%, from(#747D80), to(#545D60));
  background: -webkit-linear-gradient(#747D80, #545D60);
  background: -moz-linear-gradient(#747D80, #545D60);
  background: -o-linear-gradient(#747D80, #545D60);
  background: linear-gradient(#747D80, #545D60);
  -webkit-transform: skew(-45deg);
  -moz-transform: skew(-45deg);
  transform: skew(-45deg);
}
.rect:hover {
  background: -webkit-gradient(linear, 0 0, 0 100%, from(#545D60), to(#949DA0));
  background: -webkit-linear-gradient(#545D60, #949DA0);
  background: -moz-linear-gradient(#545D60, #949DA0);
  background: -o-linear-gradient(#545D60, #949DA0);
  background: linear-gradient(#545D60, #949DA0);
}
.rect:hover:before {
  background: -webkit-gradient(linear, 0 0, 0 100%, from(#545D60), to(#747D80));
  background: -webkit-linear-gradient(#545D60, #747D80);
  background: -moz-linear-gradient(#545D60, #747D80);
  background: -o-linear-gradient(#545D60, #747D80);
  background: linear-gradient(#545D60, #747D80);
}
.rect:hover:after {
  background: -webkit-gradient(linear, 0 0, 0 100%, from(#747D80), to(#949DA0));
  background: -webkit-linear-gradient(#747D80, #949DA0);
  background: -moz-linear-gradient(#747D80, #949DA0);
  background: -o-linear-gradient(#747D80, #949DA0);
  background: linear-gradient(#747D80, #949DA0);
}
<div class="rect"><span>NEXT</span>
</div>
Harry
  • 87,580
  • 25
  • 202
  • 214
  • 1
    Hey it has a hover. `z-index: -1;` on `:before` won't work properly. – The Pragmatick Jan 31 '15 at 06:48
  • @Harry I need to hover the button also. –  Jan 31 '15 at 06:52
  • @ThePragmatick: You don't need a hover on the `:before` element. You can change them on hover of main element. – Harry Jan 31 '15 at 06:54
  • @JakeMikail: Please check the updated snippet for hover effect. Only issue is the border-radius on left goes missing when hover. I will fix it soon. *Edit:* It seems like the hover causes border-radius on left to disappear only on lower versions of Chrome. Works fine in other latest. – Harry Jan 31 '15 at 06:58
  • @Harry works just fine! Didn't see that you have 2 pseudo elements. – The Pragmatick Jan 31 '15 at 06:59
  • i am having some problem again. hovering isn't working on mobile tap. how can I fix this? thanks again. –  Mar 03 '15 at 13:30
  • @JakeMikail: I just tried in my iPhone (Safari) and it works fine. And as long as the browser version supports gradients this should work in other phones also. – Harry Mar 03 '15 at 14:08