Rounded arrow shape with gradient fill - html

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>
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.

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>

Related

CSS Responsive banner with oblique shadow

I'm trying to create a background for a banner using css where one side has a color and on the other side has another one with a 45° cut like this
I've been able to recreate the above image except for the drop shadow that doesn't stay in the right position.
Any advice would be greatly appreciated.
This is my code code:
#container {
height: 100px;
width: 400px;
overflow: hidden;
background-color: #2962ff;
}
#triangle-topleft {
width: 0;
height: 0;
border-top: 100px solid #2196f3;
border-right: 400px solid transparent;
-webkit-box-shadow: 5px 5px 20px 0px rgba(0,0,0,0.75);
-moz-box-shadow: 5px 5px 20px 0px rgba(0,0,0,0.75);
box-shadow: 5px 5px 20px 0px rgba(0,0,0,0.75);
}
<div id="container">
<div id="triangle-topleft"></div>
</div>
The CSS triangle trick with border can not be used for this, as a shadow will still be applied to the box, and not only to the triangle.
You will have to create a pseudo element, rotate it and THEN apply shadow to it.
#container {
position: relative;
height: 200px;
width: 200px;
overflow: hidden;
background-color: grey;
}
#container:before {
content: '';
position: absolute;
left: 20%;
width: 100%;
height: 200%;
background-color: rgb(255, 255, 255); /* fallback */
background-color: rgba(255, 255, 255, 0.5);
top: 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
transform: rotate(45deg);
box-shadow: inset 0 0 20px 10px #333;
}
<div id="container"></div>
Basically you create a rectangle which is larger than the parent, then rotate it and apply a shadow. You can tweak the colors and rotation-degree for your needs
Demo: http://jsfiddle.net/b5TnZ/2032/
You can add multiple color stops in Linear Gradients. Use two color set.
Gradient generated using Shapy
.canvas {
display: flex;
height: 100vh;
align-items: center;
justify-content: center;
min-height: 100%;
min-width: 100%;
}
.gradient-canvas {
max-height: 100%;
max-width: 100%;
width: 100%;
height: 100%;
background: linear-gradient(127deg, rgb(31, 163, 209) 0%, rgb(31, 163, 209) 50%, rgb(25, 64, 208) 0%, rgb(46, 101, 223) 52%) 50% 50% / 100% 100% no-repeat;
}
<div class="canvas"><div class="gradient-canvas"></div></div>
You can try gradient like below:
#container {
height: 150px;
background:
linear-gradient(135deg,#2962ff 49.8%,rgba(0,0,0,0.75) 50%, #2196f3 calc(50% + 10px));
background-color:#2196f3;
}
<div id="container">
</div>
And simply replace the deg with to bottom right if you want the diagonal result:
#container {
height: 150px;
width:50%;
background:
linear-gradient(to bottom right,#2962ff 50%,rgba(0,0,0,0.75) 50%, #2196f3 calc(50% + 10px));
background-color:#2196f3;
}
<div id="container">
</div>

Divide a rectangle into 2 triangles along diagonal using css

I want to make a div into 2 triangles (as shown in below, no problem if 1 is background of parent) upper one with one color and lower one with another. I dont mind how it is implemented but i want to do it in css (not javascript). I tried with css rotation, (code below), but its not responsive. In smaller or wider screen it is distorted . Any way to implement this in css?
body {
background: #eee;
}
.darker {
position: fixed;
top: -94%;
left: -10%;
width: 150%;
height: 150%;
background: #dd4f39;
-webkit-transform: rotate(30deg);
transform: rotate(30deg);
}
<div class="darker"> </div>
I found an interesting way to do this from here, which uses clip-path
.Answering my own question so that everyone can use it.
html,
body {
margin: 0;
}
body {
background: #eee;
}
.box {
width: 100vw;
height: 100vh;
background-color: #dd4f39;
clip-path: polygon(0 0, 100% 0, 100% 100%);
}
<div class="box"></div>
This is one way of doing it. But this use case is strictly with respect to vw. Just make sure to give the same value to these elements
div and it's pseudo element should have same width and border-left respectively.
div and it's pseudo element should have same height and border-top respectively.
html, body {
margin: 0;
}
.box {
width: 100vw;
height: 100vh;
background-color: white;
}
.box::after {
content: ' ';
border-top: 100vh solid #dd4f39;
border-left: 100vw solid transparent;
width: 0;
position: absolute;
}
<div class="box"></div>
JS fiddle
https://jsfiddle.net/kqsrmrss/2/
You can do that with a skewed pseudo element. The main trick is to keep the aspect ratio the same or else the sloped angle will fail
Fiddle demo
Stack snippet Note 1
body {
background: #eee;
}
.darker {
position: absolute;
top: 0;
left: 0;
width: 100%;
padding-top: 50%;
background: #dd4f39;
overflow: hidden;
}
.darker::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: gray;
transform: skewY(26.5deg);
transform-origin: left top;
}
<div class="darker"></div>
Optionally, you can add media query to control the angle at different screen sizes
Fiddle demo 2
With a tiny script running when window resize's, you can control the angle and make it fully responsive both horizontally and vertically.
Note 1 Based on a comment, the Stack snippet might not work properly, and if, try the fiddle demos.
Please Use this code snippet.
div {
width: 100%;
height: 100px;
}
.diagonalRising {
border: 1pt solid black;
background: linear-gradient(to right bottom, #eeeeee 0%, #eeeeee 49.9%, #eeeeee 50%, #000000 51%, #dd4f39 51.1%, #dd4f39 100%);
}
.diagonalFalling {
background: linear-gradient(to right top, #eeeeee 0%, #eeeeee 49.9%, #000000 50%, #000000 51%, #dd4f39 51.1%, #dd4f39 100%);
}
.diagonalCross {
position: relative;
background: linear-gradient(to right bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 49.9%, rgba(0, 0, 0, 1) 50%, rgba(0, 0, 0, 1) 51%, rgba(0, 0, 0, 0) 51.1%, rgba(0, 0, 0, 0) 100%);
}
.diagonalCross:after {
content: "";
display: block;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: -1;
background: linear-gradient(to right top, #ffffff 0%, #ffffff 49.9%, #000000 50%, #000000 51%, #ffffff 51.1%, #ffffff 100%);
}
<div class="diagonalRising"></div>
<div class="diagonalFalling"></div>
<div class="diagonalCross"></div>
Try this,
.box::after {
background: #E52A35
content: '';
position: absolute;
width: 100%;
height: 100vh;
background-color: #dd4f39;
clip-path: polygon(52% 13%, 104% -1%, -1% 0%);
}

Create transparent css border with triangle

I'm trying the find a way to have a dynamic border with a triangle. For the moment, with the basic gradient effect, this is what I did:
My current effect in action
But as you can see, the background has a gradient and we can see the border background that does not match..
How can I achieve this effect? Also, the text may vary on different screen size and with other words.
Thank you!
Using pseudo-elements and skewX is one clean way to achieve this. Check this out, I'm using a top, left & right border on the element, and then style the before as the left bottom border and the after as the right one:
body {
background-color: white;
background-image: linear-gradient(45deg, #999 25%, transparent 25%, transparent 75%, black 75%, black), linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, #999 75%, #999);
background-size: 10px 10px;
background-position: 0 0, 50px 50px;
}
.dialog {
text-align: center;
color: green;
font-size: 65px;
width: 300px;
height: 120px;
background-color: transparent;
border-width: 5px 5px 0 5px;
border-color: red;
border-style: solid;
display: inline-block;
position: relative;
}
.dialog:before {
content: '';
border-top: 5px solid red;
border-right: 5px solid red;
transform-origin: left top;
transform: skewX(45deg);
position: absolute;
content: ' ';
height: 10px;
width: 46%;
background: inherit;
left: -5px;
bottom: -10px;
}
.dialog:after {
content: '';
border-top: 5px solid red;
border-left: 5px solid red;
transform-origin: left top;
transform: skewX(-45deg);
position: absolute;
content: ' ';
height: 10px;
width: 46%;
background: inherit;
right: -5px;
bottom: -10px;
}
<div class="dialog">Here I am</div>
To achieve this you can make it with a background image, for exemple http://bootsnipp.com/snippets/featured/carousel-reviews-with-rating.
As you can see he take an image and resize it to take only a triangle like this:
.sprite-i-triangle {
background-position: 0 -1298px;
height: 44px;
width: 50px;
}
Try to find an image that meets your expectations. Otherwise you have some exemples in this site. (http://bootsnipp.com)

Creating responsive eye focus icon

I've been trying to make responsive colored eye focus icon, but so far all I've tried has been unsuccessful.
I was trying to somewhat replicate the colors of a real eye.
I used border, box shadow, to get the colors, but that part is not scaling. Tried with outline too, but failed as well, that one wasn't even round.
The height of the div is currently static, but I would like it to be responsive. So the whole eye scales properly across different sizes.
Here's my code:
<div class="paragraph eye-focus">
<div class="eye1" width="80%">
<div class="eye2"></div>
</div>
</div>
.eye1 {
height: 200px;
height: calc(attr(width) / 2.5);
width: 75%;
background-color: white;
border-radius: 50%;
position: relative;
margin: auto;
}
.eye2 {
background-color: black;
width: 8%;
height: 12%;
border-radius: 50%;
border: 0.5em solid #a50;
box-shadow: 0 0 0 1.5em #080;
position: absolute;
top: 40%;
left: 45%;
}
.eye-focus {
position: relative;
}
jsfiddle if you'd prefer https://jsfiddle.net/xcxdp92q/
I'd like to put my solution out there.
You can use background radial-gradient to create the eye in a single element.
When adding padding in %, it is based on the width of the element. Use that to your advantage to make it responsive. If padding equals width, the element will be a square.
.eye-focus {
box-sizing: content-box;
height: 0;
width: 75%;
padding: 30% 0 0 0;
margin: 0 auto;
border-radius: 50%;
background-color: #fff;
background-image: radial-gradient(circle, #000 8%, #a50 8%, #0b0 17%, #080 33%, transparent 33%);
}
<div class="paragraph">
<div class="eye-focus"></div>
</div>
jsfiddle
If you're only supporting browsers that support gradients (and current browsers most do) then you can just use one div and do all the colors in a radial gradient. I used vw to size it like Suthan Bala suggested in their comment.
body {
background: #EEE;
}
.eye {
border-radius: 50%;
background: -moz-radial-gradient(center, ellipse cover, #000000 17%, #aa5500 18%, #008800 40%, #ffffff 41%);
background: -webkit-radial-gradient(center, ellipse cover, #000000 17%, #aa5500 18%, #008800 40%, #ffffff 41%);
background: radial-gradient(ellipse at center, #000000 17%, #aa5500 18%, #008800 40%, #ffffff 41%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#ffffff', GradientType=1);
width: 35vw;
height: 35vw;
}
<div class="eye">
</div>
I used the Color Gradient Generator by Colorzilla.
Try using this CSS:
.eye1 {
height: 4vw;
width: 4vw;
background-color: white;
border-radius: 50%;
position: relative;
margin: auto;
}
.eye2 {
background-color: black;
width: 6vw;
height: 6vw;
border-radius: 50%;
border: 1em solid #a50;
box-shadow: 0 0 0 3vw #080;
position: relative;
top: 8vw;
left: 43%;
}
.eye-focus {
position: relative;
}
I've been using vw a lot lately (for a year now). Very handy!

Dotted top and bottom border shorter than text

I want to achieve border top and bottom like below image how can I achieve with CSS tricks?
Challenge is I don't want entire width with border and it should be responsive too.
Mobile version image is http://i.imgur.com/XZTW28N.jpg and it should work in desktop and mobile browser too.
I tried with %width border but it's not working.
I wrote below code but it's not 100% perfect answer for me.
HTML:
<h1>How it Works</h1
CSS:
h1:before, h1:after {
content: "";
height: 1px;
background: linear-gradient(to right, rgba(0,0,0,0) 0%,rgba(147,147,147,1) 50%,rgba(0,0,0,0) 100%);
display: block;
margin-bottom: 10px;
margin-top: 10px;
}
http://jsfiddle.net/wjhnX/488/
I made a few changes in your CSS:
h1{
text-align: center;
font-size: 70px;
}
h1:before, h1:after{
position: relative;
content: "";
width: 30%;
left: 35%;
display: block;
margin-bottom: 10px;
margin-top: 10px;
border-bottom: 5px dotted yellow;
}
DEMO
EDIT:
If you want a fixed width you can add:
h1:before, h1:after{
width: 150px; /* You can change this value */
left: 50%;
transform: translateX(-50%);
}
DEMO2
You can use box-shadows also to achieve this, first create an after psuedo-element on top and a before pseudo-element on bottom then give the two of the box-shadows
body{
background:#09858F;
}
div{
position:relative;
display:inline-block;
margin:100px;
}
h1{
text-align:center;
font-family: Calibri;
font-size:50px;
color:#fff;
margin:50px;
}
h1:after{
content:"";
position:absolute;
left:30%;
height:10px;
width:10px;
background:yellow;
top:20%;
border-radius:50%;
box-shadow:20px 0 0 0 yellow,40px 0 0 0 yellow,60px 0 0 0 yellow,80px 0 0 0 yellow,100px 0 0 0 yellow,120px 0 0 0 yellow,140px 0 0 0 yellow,160px 0 0 0 yellow;
}
h1:before{
content:"";
position:absolute;
left:30%;
height:10px;
width:10px;
background:yellow;
bottom:20%;
border-radius:50%;
box-shadow:20px 0 0 0 yellow,40px 0 0 0 yellow,60px 0 0 0 yellow,80px 0 0 0 yellow,100px 0 0 0 yellow,120px 0 0 0 yellow,140px 0 0 0 yellow,160px 0 0 0 yellow;
}
<div><h1>How it Works</h1></div>
Here is another approach using radial-gradient background image to produce the dots at the top and bottom. The output is responsive and the no. of dots at the top and bottom are determined by the width (for example, width: 108px produces 9 dots as background-size in x-axis is 12px).
The advantage of this approach over the others is that this allows greater control over the size of the dots and the space in between the dots. The downside is the browser support for radial-gradient which is lower (IE10+) compared to dotted border method.
h1 {
position: relative;
text-align: center;
font-size: 48px;
line-height: 1em;
padding: 0.625em;
font-family: Calibri;
font-weight: 100;
}
h1:after {
position: absolute;
content: '';
width: 108px; /* multiples of background-size in X-axis */
height: 100%;
top: 0px;
left: calc(50% - 50px);
background: radial-gradient(circle at 50% 50%, rgb(250, 189, 38) 30%, transparent 50%), radial-gradient(circle at 50% 50%, rgb(250, 189, 38) 30%, transparent 50%);
background-size: 12px 6px;
background-repeat: repeat-x;
background-position: 50% 0.125em, 50% 2em;
}
/* Just for demo */
body {
background: rgb(9, 133, 143);
color: white;
}
<!-- library included to support older browsers -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<h1>How it works</h1>
<h1>How it works with long text</h1>
Screenshot with large dots:
All that is needed to be done to make the dots smaller in size is to reduce the color-stop percentages of the radial gradient. The smaller the percentages, the smaller the dots.
h1 {
position: relative;
text-align: center;
font-size: 48px;
line-height: 1em;
padding: 0.625em;
font-family: Calibri;
font-weight: 100;
}
h1:after {
position: absolute;
content: '';
width: 108px; /* multiples of background-size in X-axis */
height: 100%;
top: 0px;
left: calc(50% - 50px);
background: radial-gradient(circle at 50% 50%, rgb(250, 189, 38) 25%, transparent 35%), radial-gradient(circle at 50% 50%, rgb(250, 189, 38) 25%, transparent 35%);
background-size: 12px 6px;
background-repeat: repeat-x;
background-position: 50% 0.125em, 50% 2em;
}
/* Just for demo */
body {
background: rgb(9, 133, 143);
color: white;
}
<!-- library included to support older browsers -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<h1>How it works</h1>
<h1>How it works with long text</h1>
Screenshot with smaller dots: