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.
Related
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
Hi i've got a input range on html5 min 0 and max 100.
But i would like to color a part for example between 70 and 100.
I don't want to use bootstrap for this.
I don't know how to do that.
You can easily do this by using a linear-gradient as background for the track. All that we need to do is create a gradient which is colored only for the width that we need (30% for your case because you need it colored only between 70-100) and then position it with respect to the track's (the track is the bar of the range input) right side. Since the styling of range inputs is still in experimental phase we have to use browser prefixed selectors (to select the track of each browser) and then apply styles to it. We also have to do some additional corrections to address browser specific problems, I've marked these with inline comments in the code.
The below code is tested and found to be working fine in Edge, IE11 and latest versions of Chrome, Firefox and Opera (all on a Windows 10 machine).
Note: This will only color the part between 70-100 of the range input differently. This doesn't have the code to make the appearance of range input the same in all browsers. I've not done that because that is out of the scope of this question.
Also, as mentioned by ssc-hrep3 in his comment, this may not be good for production implementation because these things are still in experimental stage and we've to use browser specific selectors but if you want to apply custom styling to HTML5 range inputs then there is probably no other way.
input[type=range] {
-webkit-appearance: none;
border: 1px solid black; /* just for demo */
}
input[type=range]::-webkit-slider-runnable-track {
background: linear-gradient(to left, red 30%, transparent 30%);
background-position: right top;
}
input[type=range]::-moz-range-track {
background: linear-gradient(to left, red 30%, transparent 30%);
background-position: right top;
}
input[type=range]::-ms-track {
background: linear-gradient(to left, red 30%, transparent 30%);
background-position: right top;
background-repeat: no-repeat; /* no repeat means background appears a little on the left due to width issue and hence the fix */
width: 100%; /* to fix width issue in Edge */
color: transparent; /* to avoid the intermediate stripe lines in < IE11 */
border: none; /* just do away with the track's border */
}
input[type=range]::-ms-fill-lower {
background: transparent; /* IE11 has default fill and that needs to be removed */
}
<input type="range" min="0" max="100" value="70" step="10" />
For the benefit of future readers: Just in case you need uniform styling across all major browsers then you could use the below snippet. It produces almost similar output in all of them.
input[type=range] {
-webkit-appearance: none;
}
input[type=range]::-webkit-slider-runnable-track {
background: linear-gradient(to left, red 30%, transparent 30%);
background-position: right top;
height: 10px;
box-shadow: inset 0px 0px 0px 1px black;
}
input[type=range]::-moz-range-track {
background: linear-gradient(to left, red 30%, transparent 30%);
background-position: right top;
height: 10px;
box-shadow: inset 0px 0px 0px 1px black;
}
input[type=range]::-ms-track {
background: linear-gradient(to left, red 30%, transparent 30%);
background-position: right top;
background-repeat: no-repeat; /* no repeat means background appears a little on the left due to width issue and hence the fix */
width: 100%; /* to fix width issue in Edge */
height: 10px;
color: transparent; /* to avoid the intermediate stripe lines in < IE11 */
border-color: transparent;
border-style: solid;
border-width: 10px 0px; /* dummy just to increase height, otherwise thumb gets hidden */
box-shadow: inset 0px 0px 0px 1px black;
}
input[type=range]::-ms-fill-lower {
background: transparent; /* IE11 has default fill and that needs to be removed */
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
height: 18px;
width: 18px;
margin-top: -4px;
background: sandybrown;
border: 1px solid chocolate;
border-radius: 50%;
}
input[type=range]::-moz-range-thumb {
height: 18px;
width: 18px;
background: sandybrown;
border: 1px solid chocolate;
border-radius: 50%;
}
input[type=range]::-ms-thumb {
height: 18px;
width: 18px;
margin-top: 0px; /* nullify default margin */
background: sandybrown;
border: 1px solid chocolate;
border-radius: 50%;
}
<input type="range" min="0" max="100" value="70" step="10" />
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
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
I want transparent text from which background should be visible but text shadow should be opaque.
I tried:
opacity:0;
text-shadow 3px 3px 3px orange;
but text-shadow also becomes transparent.
I want result like this:
http://blog.tmimgcdn.com/wp-content/uploads/2011/07/Glowing-Polkadots-Text-Effect.jpg?9d7bd4
Please help.
You can get this effect in modern browsers (Chrome, Safari and FF) using a blend mode option
.test {
font-size: 360px;
position: relative;
border: solid 1px;
display: inline-block;
margin: 5px;
text-shadow: orange 10px 0px 30px, orange -10px 0px 30px, orange 0px 10px 30px, orange 0px -10px 30px;
color: black;
background: black;
mix-blend-mode: screen;
}
body {
background-image: url(http://i.stack.imgur.com/08Y1e.jpg);
}
<div class="test">STAR FIELD</div>
I uploaded the background image to avoid problems with the link
if you have a solid background, you can try this way:
http://jsfiddle.net/aKp3C/
<div class="content">
<div class="text text1">
Example text
</div>
<div class="text text2">
Example text
</div>
</div>
body{
background-color: #333;
}
.content{
position: relative;
}
.text{
font-size: 25px;
font-weight: bold;
}
.text1{
text-shadow: 3px 3px 3px orange;
}
.text2{
position: absolute;
left: 0;
top: 0;
color: #333;
}
You could use the text-shadow-blend-mode CSS3 property for that purpose.
However, it seems it is not yet supported (Firefox 39.0 ignores it completely).
I am also struggling with (semi-)transparent text outlining. The problem is, text-shadow doesn't really generate outlines but duplicates the text behind its foreground and eventually shifts and blurs it. (Any text whose color is not opaque will be blend together with its own shadow at first.)
Currently, this may not be doable using CSS.
EDIT: You might, however, find useful this advice involving SVG and its stroke property.