CSS Gradient arrow shape with inner shadow and gradient border - css

I want to create a gradient arrow shape button with gradient border and 1px inner shadow from CSS.
I've created an image to show the button and the style rules:
This is what I have so far:
.button {
color: #FFF;
background-color: #D02180 !important;
background: -webkit-gradient(linear, 0 0, 0 100%, from(#f84aa4), to(#d02181));
background: -webkit-linear-gradient(#f84aa4, #d02181);
background: -moz-linear-gradient(#f84aa4, #d02181);
background: -o-linear-gradient(#f84aa4, #d02181);
background: linear-gradient(#f84aa4, #d02181);
padding: 5px 10px;
border-radius: 6px;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
border: 1px solid #ab1465;
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.4) inset;
}
<a class="button">Next</a>
Cross-browser support is a main thing so it's also ok if everything can be done from CSS expect the gradient border. In this case the border will have one simple color — #ab1465.
The main problem starts with the gradient. I can make an arrow shape with the help of css pseudo elements, but I need a cross browser solution to have one continuous gradient for the whole arrow shape.

Gradient Arrow Button
Let's get creative!
This button has been created entirely with CSS — skew, border and gradient with pseudo elements. It looks like this:
It looks nice zoomed in and doesn't break:
This is the shape that creates it:
The shape is cut off with overflow: hidden on the parent.
The CSS
Create the angled shape and gradient with the :before.
The inner shadow is created with the :after using a simple border
The gradient is given an angle to match the direction of the pseudo elements rotation
Note the use of transform: translateZ(0). This prevents a jagged appearance of the rotated pseudo element. Currently the pseudo element is placed underneath the text with z-index: -1.
Complete Example
You will need to tinker with the fine details, but it should speak for itself. In order to take more text, the pseudo element with the gradient would need to be larger.
#import url(http://fonts.googleapis.com/css?family=Exo+2:300);
a {
color: #000;
text-decoration: none;
position: relative;
color: #FFF;
display: inline-block;
padding: 10px 40px 10px 10px;
border-radius: 5px;
overflow: hidden;
transform: translateZ(0);
font-family: 'Exo 2', sans-serif;
}
img {
position: relative;
z-index: -1;
}
a:before {
content: '';
display: block;
position: absolute;
top: 50%;
margin-top: -2.4em;
left: -20%;
width: 100%;
height: 200%;
background: #D02180 linear-gradient(130deg, rgba(248, 74, 165, 1) 30%, rgba(248, 74, 165, 1) 80%);
transform: rotate(55deg) skewX(20deg) translateZ(0);
z-index: -1;
}
a:after {
content: '';
display: block;
position: absolute;
top: 1px;
left: 1px;
width: 70%;
height: 100%;
transform: translateZ(0);
z-index: -1;
border-top: solid 1px #FFF;
border-radius: 5px 0;
opacity: 0.4;
}
Next

Related

How to create Button with cut edges? [duplicate]

I'm looking for an easy way with a single tag (just <a>)to create a skew effect on the borders, but keep the text the way it is.
I would know how do with a span in- or outside, but I don't want to have additional, pretty much zero meaning HTML on the page.
Example below.
You can unskew the child element i.e. provide the opposite skew co-ordinates as you specified for the parent.
Here is a working example
Suppose you have below as you html,
<div class="btn">
<button><div class="btn-text">Click</div></button>
</div>
If we skew the parent element by 20deg then we should skew the child element by -20deg as,
.btn {
-ms-transform: skewX(20deg); /* IE 9 */
-webkit-transform: skewX(20deg); /* Safari */
transform: skewX(20deg);
}
.btn-text {
-ms-transform: skewX(-20deg); /* IE 9 */
-webkit-transform: skewX(-20deg); /* Safari */
transform: skewX(-20deg);
padding: 20px;
}
You can simply accompish desired effect using CSS triangle tricks.
Just add some styles for the ::before and :: after pseudo-classes.
.skewed_button {
background: #32CD32;
color: #000;
text-decoration: none;
font-size: 20px;
display: inline-block;
height: 30px;
margin-left: 15px;
padding: 6px 10px 0;
}
.skewed_button::before {
content: "";
float: left;
margin: -6px 0 0 -25px;
border-left: 15px solid transparent;
border-bottom: 36px solid #32CD32;
height: 0px;
}
.skewed_button::after {
content: "";
float: right;
margin: -6px -25px 0 0 ;
border-left: 15px solid #32CD32;
border-bottom: 36px solid transparent;
height: 0px;
}
Some Text
You can also use clip-path for this, eg:
clip-path: polygon(14px 0%, 100% 0%, calc(100% - 14px) 100%, 0% 100%);
.skewed_button {
background: yellow;
text-decoration: none;
display: inline-block;
padding: 10px 20px;
clip-path: polygon(14px 0%, 100% 0%, calc(100% - 14px) 100%, 0% 100%);
}
Some Text
One solution is to use css triangles on :before and :after. This solution leaves the cleanest HTML.
This jsfiddle demonstrates
.is-skewed {
width: 80px;
height: 40px;
background-color: #f07;
display: block;
color: #fff;
margin-left: 40px;
}
.is-skewed:before,
.is-skewed:after {
content: '';
width: 0;
height: 0;
}
.is-skewed:before {
border-bottom: 40px solid #f07;
border-left: 20px solid transparent;
float:left;
margin-left: -20px;
}
.is-skewed:after {
border-top: 40px solid #f07;
border-right: 20px solid transparent;
float:right;
margin-right: -20px;
}
CSS triangles use thick borders on elements with 0 dimensions with the points at which the borders meet providing the diagonal line required for a triangle (a good visualisation is to look at the corner of a picture frame, where the two borders meet and create triangles). It's important that one border is transparent and one coloured and that they are adjacent (i.e. left and top, not left and right). You can adjust the size, orientation and the lengths of the sides by playing with the border sizes.
For your button, we also use floats and negative margins to pull them outside of the element and line them up right. Position absolute and negative left and right values would also be a good solution to positioning
You can also do :hover states
.is-skewed:hover {
background-color: #40f;
}
.is-skewed:hover:after {
border-top-color: #40f;
}
.is-skewed:hover:before {
border-bottom-color: #40f;
}
It's important to note the use of background-color and border-color and also that the :hover comes first in all the relevant selectors. If the hover came second this would happen

Css overlay for focusing on button

Is there a way in css to create and overlay with opacity 0.5
And create a class that when applied will somehow affect the overlay so the final result will look something like this?
What I am looking for a way that the class would affect the overlay.
I don't know how the rest of your page looks like, but you can use a pseudo-element (to get an offset) with box-shadow to punch a hole around an element, simply by adding a class to the element you want to highlight. Needs some fine adjustment, if you got other shapes than rectangles.
div {
box-shadow: 0px 0px 10px 1px lightgrey;
border-radius: 1rem;
padding: 1rem;
}
button {
background-color: blue;
color: white;
padding: 0.5rem 1rem;
border-radius: 1rem;
cursor: pointer;
}
.highlight {
position: relative;
}
.highlight::before {
--white-area: -25px;
content: '';
position: absolute;
left: var(--white-area);
right: var(--white-area);
top: var(--white-area);
bottom: var(--white-area);
box-shadow:
inset 0px 0px 10px 0px rgba(0, 0, 0, 0.5),
0px 0px 0px 9999px rgba(0, 0, 0, 0.3);
pointer-events: none;
border-radius: 2rem;
}
<div>
<h3>Don't Have an Account?</h3>
<button class="highlight">Create Your Account</button>
</div>
You can easily create an overlay with css. But AFAIK there is no way to "punch a hole" into that overlay. But you might put your button above the overlay and give it a (in this case white) shadow. So you would have to apply a class to the button rather than to the overlay.
EDIT:
As Simon shows, there IS a way to make a hole - but there would be a severe issue: How do you find the position above your button in a responsive design?
I still would recommend putting the button ABOVE the overlay.
A way is to create an overlay, and put the button on top of it, using z-index.
button{
background-color: #3499eb;
padding: 10px;
position: relative;
z-index: 999;
color: #fff;
}
.overlay{
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left:0;
background-color: black;
opacity: 0.5;
}
<div class="overlay"></div>
<button>Click here </button>

On focus of div change background to gray with styled-components

I have this div in styled components
const StyledDots = styled.div`
width: 16px;
height: 16px;
border: solid 1px #d2d2d2;
border-radius: 20px;
background-color: #ffffff;
position: relative;
top: 50px;
right: 15px;
::focus {
background: black;
} `
I tried to change background color to gray with focus but as you see I'm doing something wrong and i Dont know what,Any suggestions please?
(Would be better if only 50% of the div will change the color)
to change style onHover, onFocus, ...etc with styled components you need to use this syntax:
&:focus {
background: black;
}
for background to be 50% of the height you can use linear-gradient to set the background color:
&:focus {
background: linear-gradient(180deg, black 50%, white 50%);
}

CSS: Skew a buttons border, not the text

I'm looking for an easy way with a single tag (just <a>)to create a skew effect on the borders, but keep the text the way it is.
I would know how do with a span in- or outside, but I don't want to have additional, pretty much zero meaning HTML on the page.
Example below.
You can unskew the child element i.e. provide the opposite skew co-ordinates as you specified for the parent.
Here is a working example
Suppose you have below as you html,
<div class="btn">
<button><div class="btn-text">Click</div></button>
</div>
If we skew the parent element by 20deg then we should skew the child element by -20deg as,
.btn {
-ms-transform: skewX(20deg); /* IE 9 */
-webkit-transform: skewX(20deg); /* Safari */
transform: skewX(20deg);
}
.btn-text {
-ms-transform: skewX(-20deg); /* IE 9 */
-webkit-transform: skewX(-20deg); /* Safari */
transform: skewX(-20deg);
padding: 20px;
}
You can simply accompish desired effect using CSS triangle tricks.
Just add some styles for the ::before and :: after pseudo-classes.
.skewed_button {
background: #32CD32;
color: #000;
text-decoration: none;
font-size: 20px;
display: inline-block;
height: 30px;
margin-left: 15px;
padding: 6px 10px 0;
}
.skewed_button::before {
content: "";
float: left;
margin: -6px 0 0 -25px;
border-left: 15px solid transparent;
border-bottom: 36px solid #32CD32;
height: 0px;
}
.skewed_button::after {
content: "";
float: right;
margin: -6px -25px 0 0 ;
border-left: 15px solid #32CD32;
border-bottom: 36px solid transparent;
height: 0px;
}
Some Text
You can also use clip-path for this, eg:
clip-path: polygon(14px 0%, 100% 0%, calc(100% - 14px) 100%, 0% 100%);
.skewed_button {
background: yellow;
text-decoration: none;
display: inline-block;
padding: 10px 20px;
clip-path: polygon(14px 0%, 100% 0%, calc(100% - 14px) 100%, 0% 100%);
}
Some Text
One solution is to use css triangles on :before and :after. This solution leaves the cleanest HTML.
This jsfiddle demonstrates
.is-skewed {
width: 80px;
height: 40px;
background-color: #f07;
display: block;
color: #fff;
margin-left: 40px;
}
.is-skewed:before,
.is-skewed:after {
content: '';
width: 0;
height: 0;
}
.is-skewed:before {
border-bottom: 40px solid #f07;
border-left: 20px solid transparent;
float:left;
margin-left: -20px;
}
.is-skewed:after {
border-top: 40px solid #f07;
border-right: 20px solid transparent;
float:right;
margin-right: -20px;
}
CSS triangles use thick borders on elements with 0 dimensions with the points at which the borders meet providing the diagonal line required for a triangle (a good visualisation is to look at the corner of a picture frame, where the two borders meet and create triangles). It's important that one border is transparent and one coloured and that they are adjacent (i.e. left and top, not left and right). You can adjust the size, orientation and the lengths of the sides by playing with the border sizes.
For your button, we also use floats and negative margins to pull them outside of the element and line them up right. Position absolute and negative left and right values would also be a good solution to positioning
You can also do :hover states
.is-skewed:hover {
background-color: #40f;
}
.is-skewed:hover:after {
border-top-color: #40f;
}
.is-skewed:hover:before {
border-bottom-color: #40f;
}
It's important to note the use of background-color and border-color and also that the :hover comes first in all the relevant selectors. If the hover came second this would happen

Button with beveled edge on semi-transparent background

I'm trying to create a button with CSS that will sit on a semi-transparent background that has a beveled or cut edge to it. Here is the Photoshop mockup:
I'm able to do this successfully with a solid color background because I can use an pseudo element with that same background and "cover" the edge of the button, but it doesn't work with a semi-transparent background.
Here's what I've got so far, on a solid background: http://codepen.io/anon/pen/GJFpc
I'm beginning to believe this isn't possible with just CSS, but still hoping S.O. can save me once again!
I love a good css challenge so I tried a few things and this is what I could come up with:
http://jsfiddle.net/QE67v/3/
The css (unprefixed) looks like this:
a.cta {
position: relative;
float: left;
padding: 8px 10px;
text-align: center;
text-decoration: none;
text-transform: uppercase;
font-size: 15px;
font-weight: normal;
background-image: linear-gradient(top, #ffffff 0%, #e4e4e4 100%);
box-shadow: inset 0 -2px 1px 2px #fff;
line-height: 16px;
height: 16px;
z-index: 2;
}
a.cta:after {
content: '';
display: block;
position: absolute;
width: 32px;
height: 32px;
right: -16px;
top: 0;
background-image: linear-gradient(top, #ffffff 0%, #e4e4e4 100%);
box-shadow: inset -3px -2px 1px 2px #fff;
transform: skewX(-45deg);
z-index: -1;
}
There are two main differences with your code:
I use a inset box-shadow to achieve the white 'bevel'. You could
probably do this with gradients as well, but I just find the shadows
more intuitive.
In stead of making the button wider and covering the bottom left
corner with a pseudo element in the color of the background, I kept
the button in its normal width and added a pseudo element to which a
applied the skewX transformation. This allows for any background, as
you can see by the gradient I set as a background in my fiddle.
I believe this is what you where after. Feel free to ask if you need any further help/explanation.

Resources