Dynamic height button with gradient and pointed end - css

I would like to create buttons with gradient as the background and a pointed end that will adjust to the height of the button, which depends on the amount of text inside. Page background can vary, so I can't use solid color for pointed end. The best solution I came up with is using after pseudo-element with svg code as a background-image, setting the background height to 100%, but this solution does not satisfy me too much, because I don't know if it will look good on all modern browsers. Do you have any ideas? Maybe I should use Javascript?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Button example</title>
<style>
html, body {
height: 100%;
}
body {
background-color: #e5e5e5;
}
.wrapper {
background-color: #ffffff;
padding: 15px;
max-width: 180px;
margin: 0 auto;
}
.btn {
position: relative;
display: inline-block;
background: #000000 linear-gradient(to bottom, #000000, #666666);
color: #ffffff;
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
padding: 8px 20px;
margin-right: 12px;
margin-bottom: 15px;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
.btn::after {
content: '';
position: absolute;
top: 0px;
right: -12px;
display: inline-block;
height: 100%;
width: 13px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='40'%3E%3ClinearGradient id='css-btn-example' gradientUnits='userSpaceOnUse' x1='6.5' y1='40' x2='6.5'%3E%3Cstop offset='0' stop-color='%23666'/%3E%3Cstop offset='1'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23css-btn-example)' d='M0 0h1l12 20L1 40H0z'/%3E%3C/svg%3E");
background-size: 13px 100%;
}
.btn:last-child {
margin-bottom: 0;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="btn">One line</div>
<div class="btn">Two line button example</div>
<div class="btn">Three line button long example</div>
</div>
</body>
</html>

In case the gradient will always be from top to bottom (or bottom to top), you can consider some trick using skew like below. The idea is to use the pseudo elements where you apply two different gradient that will intersect at the same color creating the illusion of one gradient.
.box {
width: 150px;
padding: 20px;
box-sizing: border-box;
position: relative;
color: #fff;
z-index: 0;
overflow: hidden;
margin:5px;
border-radius:5px 0 0 5px;
}
.box:before,
.box:after {
content: "";
position: absolute;
z-index:-1;
height: 50%;
left: 0;
right: 0;
}
.box:before {
top: 0;
background: linear-gradient(to bottom, blue, #4100bf);
transform: skewX(30deg);
transform-origin: bottom right;
}
.box:after {
bottom: 0;
background: linear-gradient(to top, purple, #4100bf);
transform: skewX(-30deg);
transform-origin: top right;
}
<div class="box">
Some text here
</div>
<div class="box">
Some text here Some text here
</div>
Another idea without transparency is to consider mutilple background and hide the gradient with a white color (or any color of the background). You can then consider any kind of gradient, even a radial-gradient.
.box {
width: 150px;
padding: 20px;
box-sizing: border-box;
color: #fff;
margin:5px;
background:
linear-gradient(to bottom right,transparent 48%,#fff 50%) bottom right/20px 50%,
linear-gradient(to top right,transparent 48%,#fff 50%) top right/20px 50%,
linear-gradient(to bottom, blue,purple);
background-repeat:no-repeat;
border-radius:5px 0 0 5px;
}
<div class="box">
Some text here
</div>
<div class="box">
Some text here Some text here
</div>
You have also the clip-path solution:
.box {
width: 150px;
padding: 20px;
box-sizing: border-box;
color: #fff;
margin: 5px;
background: linear-gradient(to bottom, blue, purple);
background-repeat: no-repeat;
border-radius: 5px 0 0 5px;
-webkit-clip-path: polygon(0% 0%, calc(100% - 20px) 0%, 100% 50%, calc(100% - 20px) 100%, 0% 100%);
clip-path: polygon(0% 0%, calc(100% - 20px) 0%, 100% 50%, calc(100% - 20px) 100%, 0% 100%);
}
<div class="box">
Some text here
</div>
<div class="box">
Some text here Some text here
</div>

Related

Creating a rectangles with corners removed + stroke in CSS [duplicate]

I'm looking to "cut" the top left corner of a div, like if you had folded the corner of a page down.
I'd like to do it in pure CSS, are there any methods?
If the parent element has a solid color background, you can use pseudo-elements to create the effect:
div {
height: 300px;
background: red;
position: relative;
}
div:before {
content: '';
position: absolute;
top: 0; right: 0;
border-top: 80px solid white;
border-left: 80px solid red;
width: 0;
}
<div></div>
http://jsfiddle.net/2bZAW/
P.S. The upcoming border-corner-shape is exactly what you're looking for. Too bad it might get cut out of the spec, and never make it into any browsers in the wild :(
CSS Clip-Path
Using a clip-path is a new, up and coming alternative. Its starting to get supported more and more and is now becoming well documented. Since it uses SVG to create the shape, it is responsive straight out of the box.
CanIUse
Clip Path Generator
div {
width: 200px;
min-height: 200px;
-webkit-clip-path: polygon(0 0, 0 100%, 100% 100%, 100% 25%, 75% 0);
clip-path: polygon(0 0, 0 100%, 100% 100%, 100% 25%, 75% 0);
background: lightblue;
}
<div>
<p>Some Text</p>
</div>
CSS Transform
I have an alternative to web-tiki's transform answer.
body {
background: lightgreen;
}
div {
width: 200px;
height: 200px;
background: transparent;
position: relative;
overflow: hidden;
}
div.bg {
width: 200%;
height: 200%;
background: lightblue;
position: absolute;
top: 0;
left: -75%;
transform-origin: 50% 50%;
transform: rotate(45deg);
z-index: -1;
}
<div>
<div class="bg"></div>
<p>Some Text</p>
</div>
If you need a transparent cut out edge, you can use a rotated pseudo element as a background for the div and position it to cut out the desired corner:
body {
background: url(http://i.imgur.com/k8BtMvj.jpg);
background-size: cover;
}
div {
position: relative;
width: 50%;
margin: 0 auto;
overflow: hidden;
padding: 20px;
text-align: center;
}
div:after {
content: '';
position: absolute;
width: 1100%; height: 1100%;
top: 20px; right: -500%;
background: rgba(255,255,255,.8);
transform-origin: 54% 0;
transform: rotate(45deg);
z-index: -1;
}
<div>
... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>
</div>
Note that this solution uses transforms and you need to add the required vendor prefixes. For more info see canIuse.
To cut the bottom right edge, you can change the top, transform and transform-origin properties of the pseudo element to:
body {
background: url(http://i.imgur.com/k8BtMvj.jpg);
background-size: cover;
}
div {
position: relative;
width: 50%;
margin: 0 auto;
overflow: hidden;
padding: 20px;
text-align: center;
}
div:after {
content: '';
position: absolute;
width: 1100%; height: 1100%;
bottom: 20px; right: -500%;
background: rgba(255,255,255,.8);
transform-origin: 54% 100%;
transform: rotate(-45deg);
z-index: -1;
}
<div>
... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>... content ...<br/>
</div>
Here is another approach using CSS transform: skew(45deg) to produce the cut corner effect. The shape itself involves three elements (1 real and 2 pseudo-elements) as follows:
The main container div element has overflow: hidden and produces the left border.
The :before pseudo-element which is 20% the height of the parent container and has a skew transform applied to it. This element prodcues the border on the top and cut (slanted) border on the right side.
The :after pseudo-element which is 80% the height of the parent (basically, remaining height) and produces the bottom border, the remaining portion of the right border.
The output produced is responsive, produces a transparent cut at the top and supports transparent backgrounds.
div {
position: relative;
height: 100px;
width: 200px;
border-left: 2px solid beige;
overflow: hidden;
}
div:after,
div:before {
position: absolute;
content: '';
width: calc(100% - 2px);
left: 0px;
z-index: -1;
}
div:before {
height: 20%;
top: 0px;
border: 2px solid beige;
border-width: 2px 3px 0px 0px;
transform: skew(45deg);
transform-origin: right bottom;
}
div:after {
height: calc(80% - 4px);
bottom: 0px;
border: 2px solid beige;
border-width: 0px 2px 2px 0px;
}
.filled:before, .filled:after {
background-color: beige;
}
/* Just for demo */
div {
float: left;
color: beige;
padding: 10px;
transition: all 1s;
margin: 10px;
}
div:hover {
height: 200px;
width: 300px;
}
div.filled{
color: black;
}
body{
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<div class="cut-corner">Some content</div>
<div class="cut-corner filled">Some content</div>
The below is another method to produce the cut corner effect by using linear-gradient background images. A combination of 3 gradient images (given below) is used:
One linear gradient (angled towards bottom left) to produce the cut corner effect. This gradient has a fixed 25px x 25px size.
One linear gradient to provide a solid color to the left of the triangle that causes the cut effect. A gradient is used even though it produces a solid color because we can control size, position of background only when images or gradients are used. This gradient is positioned at -25px on X-axis (basically meaning it would end before the place where the cut is present).
Another gradient similar to the above which again produces a solid color but is positioned at 25px down on the Y-axis (again to leave out the cut area).
The output produced is responsive, produces transparent cut and doesn't require any extra elements (real or pseudo). The drawback is that this approach would work only when the background (fill) is a solid color and it is very difficult to produce borders (but still possible as seen in the snippet).
.cut-corner {
height: 100px;
width: 200px;
background-image: linear-gradient(to bottom left, transparent 50%, beige 50%), linear-gradient(beige, beige), linear-gradient(beige, beige);
background-size: 25px 25px, 100% 100%, 100% 100%;
background-position: 100% 0%, -25px 0%, 100% 25px;
background-repeat: no-repeat;
}
.filled {
background-image: linear-gradient(black, black), linear-gradient(black, black), linear-gradient(black, black), linear-gradient(black, black), linear-gradient(to bottom left, transparent calc(50% - 1px), black calc(50% - 1px), black calc(50% + 1px), beige calc(50% + 1px)), linear-gradient(beige, beige), linear-gradient(beige, beige);
background-size: 2px 100%, 2px 100%, 100% 2px, 100% 2px, 25px 25px, 100% 100%, 100% 100%;
background-position: 0% 0%, 100% 25px, -25px 0%, 0px 100%, 100% 0%, -25px 0%, 100% 25px;
}
/* Just for demo */
*{
box-sizing: border-box;
}
div {
float: left;
color: black;
padding: 10px;
transition: all 1s;
margin: 10px;
}
div:hover {
height: 200px;
width: 300px;
}
body{
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<div class="cut-corner">Some content</div>
<div class="cut-corner filled">Some content</div>
You could use linear-gradient. Let's say the parent div had a background image, and you needed a div to sit on top of that with a gray background and a dog-eared left corner. You could do something like this:
.parent-div { background: url('/image.jpg'); }
.child-div {
background: #333;
background: linear-gradient(135deg, transparent 30px, #333 0);
}
See it on CodePen
Further reading:
CSS Gradients on CSS-Tricks
Beveled corners & negative border-radius with CSS3 gradients
I have an online generator for some of the below code: https://css-generators.com/custom-corners/
You can use mask and CSS variables to have better control over the whole shape. It's responsive, transparent and allow any kind of background:
.box {
--all:0px;
width:200px;
height:150px;
display:inline-block;
margin:10px;
background:red;
-webkit-mask:
linear-gradient( 45deg, transparent 0 var(--bottom-left,var(--all)) ,#fff 0) bottom left,
linear-gradient( -45deg, transparent 0 var(--bottom-right,var(--all)),#fff 0) bottom right,
linear-gradient( 135deg, transparent 0 var(--top-left,var(--all)) ,#fff 0) top left,
linear-gradient(-135deg, transparent 0 var(--top-right,var(--all)) ,#fff 0) top right;
-webkit-mask-size:50.5% 50.5%;
-webkit-mask-repeat:no-repeat;
}
body {
background:grey;
}
<div class="box" style="--top-left:20px"></div>
<div class="box" style="--top-right:20px;--bottom-right:50px;background:radial-gradient(red,yellow)"></div>
<div class="box" style="--all:30px;background:url(https://picsum.photos/id/104/200/200)"></div>
<div class="box" style="--all:30px;--bottom-right:0px;background:linear-gradient(red,blue)"></div>
<div class="box" style="--all:50%;width:150px;background:green"></div>
<div class="box" style="--all:12%;width:150px;background:repeating-linear-gradient(45deg,#000 0 10px,#fff 0 20px)"></div>
And below in case you want to consider border:
.box {
--all:0px;
--b:pink;
width:200px;
height:150px;
display:inline-block;
margin:10px;
border:5px solid var(--b);
background:
linear-gradient( 45deg, var(--b) 0 calc(var(--bottom-left,var(--all)) + 5px) ,transparent 0) bottom left /50% 50%,
linear-gradient( -45deg, var(--b) 0 calc(var(--bottom-right,var(--all)) + 5px),transparent 0) bottom right/50% 50%,
linear-gradient( 135deg, var(--b) 0 calc(var(--top-left,var(--all)) + 5px) ,transparent 0) top left /50% 50%,
linear-gradient(-135deg, var(--b) 0 calc(var(--top-right,var(--all)) + 5px) ,transparent 0) top right /50% 50%,
var(--img,red);
background-origin:border-box;
background-repeat:no-repeat;
-webkit-mask:
linear-gradient( 45deg, transparent 0 var(--bottom-left,var(--all)) ,#fff 0) bottom left,
linear-gradient( -45deg, transparent 0 var(--bottom-right,var(--all)),#fff 0) bottom right,
linear-gradient( 135deg, transparent 0 var(--top-left,var(--all)) ,#fff 0) top left,
linear-gradient(-135deg, transparent 0 var(--top-right,var(--all)) ,#fff 0) top right;
-webkit-mask-size:50.5% 50.5%;
-webkit-mask-repeat:no-repeat;
}
body {
background:grey;
}
<div class="box" style="--top-left:20px"></div>
<div class="box" style="--top-right:20px;--bottom-right:50px;--img:radial-gradient(red,yellow);--b:white;"></div>
<div class="box" style="--all:30px;--img:url(https://picsum.photos/id/104/200/200) center/cover;--b:orange;"></div>
<div class="box" style="--all:30px;--bottom-right:0px;--img:linear-gradient(red,blue)"></div>
<div class="box" style="--all:50%;width:150px;--img:green;--b:red;"></div>
<div class="box" style="--all:12%;width:150px;--img:repeating-linear-gradient(45deg,#000 0 10px,#fff 0 20px)"></div>
Let's also add some radius:
.box {
--all:0px;
--b:pink;
width:200px;
height:150px;
display:inline-block;
margin:10px;
filter:url(#round);
}
.box::before {
content:"";
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
background:var(--img,red);
-webkit-mask:
linear-gradient( 45deg, transparent 0 var(--bottom-left,var(--all)) ,#fff 0) bottom left,
linear-gradient( -45deg, transparent 0 var(--bottom-right,var(--all)),#fff 0) bottom right,
linear-gradient( 135deg, transparent 0 var(--top-left,var(--all)) ,#fff 0) top left,
linear-gradient(-135deg, transparent 0 var(--top-right,var(--all)) ,#fff 0) top right;
-webkit-mask-size:50.5% 50.5%;
-webkit-mask-repeat:no-repeat;
}
body {
background:grey;
}
<div class="box" style="--top-left:20px"></div>
<div class="box" style="--top-right:20px;--bottom-right:50px;--img:radial-gradient(red,yellow);--b:white;"></div>
<div class="box" style="--all:30px;--img:url(https://picsum.photos/id/104/200/200) center/cover;--b:orange;"></div>
<div class="box" style="--all:30px;--bottom-right:0px;--img:linear-gradient(red,blue)"></div>
<div class="box" style="--all:50%;width:150px;--img:green;--b:red;"></div>
<div class="box" style="--all:12%;width:150px;--img:repeating-linear-gradient(45deg,#000 0 10px,#fff 0 20px)"></div>
<svg style="visibility: hidden; position: absolute;" width="0" height="0" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="round">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur" />
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" />
<feComposite in="SourceGraphic" in2="goo" operator="atop"/>
</filter>
</defs>
</svg>
This code allows you to cut corners on each side of the rectangle:
div {
display:block;
height: 300px;
width: 200px;
background: url('http://lorempixel.com/180/290/') no-repeat;
background-size:cover;
-webkit-clip-path: polygon(10px 0%, calc(100% - 10px) 0%, 100% 10px, 100% calc(100% - 10px), calc(100% - 10px) 100%, 10px 100%, 0% calc(100% - 10px), 0% 10px);
clip-path: polygon(10px 0%, calc(100% - 10px) 0%, 100% 10px, 100% calc(100% - 10px), calc(100% - 10px) 100%, 10px 100%, 0% calc(100% - 10px), 0% 10px);
}
http://jsfiddle.net/2bZAW/5552/
If you need a diagonal border instead of a diagonal corner, you can stack 2 divs with each a pseudo element:
DEMO
http://codepen.io/remcokalf/pen/BNxLMJ
.container {
padding: 100px 200px;
overflow: hidden;
}
div.diagonal {
background: #da1d00;
color: #fff;
font-family: Arial, Helvetica, sans-serif;
width: 300px;
height: 300px;
padding: 70px;
position: relative;
margin: 30px;
float: left;
}
div.diagonal2 {
background: #da1d00;
color: #fff;
font-family: Arial, Helvetica, sans-serif;
width: 300px;
height: 300px;
padding: 70px;
position: relative;
margin: 30px;
background: #da1d00 url(http://www.remcokalf.nl/background.jpg) left top;
background-size: cover;
float: left;
}
div.diagonal3 {
background: #da1d00;
color: #da1d00;
font-family: Arial, Helvetica, sans-serif;
width: 432px;
height: 432px;
padding: 4px;
position: relative;
margin: 30px;
float: left;
}
div.inside {
background: #fff;
color: #da1d00;
font-family: Arial, Helvetica, sans-serif;
width: 292px;
height: 292px;
padding: 70px;
position: relative;
}
div.diagonal:before,
div.diagonal2:before {
content: '';
position: absolute;
top: 0;
left: 0;
border-top: 80px solid #fff;
border-right: 80px solid transparent;
width: 0;
}
div.diagonal3:before {
content: '';
position: absolute;
top: 0;
left: 0;
border-top: 80px solid #da1d00;
border-right: 80px solid transparent;
width: 0;
z-index: 1;
}
div.inside:before {
content: '';
position: absolute;
top: -4px;
left: -4px;
border-top: 74px solid #fff;
border-right: 74px solid transparent;
width: 0;
z-index: 2;
}
h2 {
font-size: 30px;
line-height: 1.3em;
margin-bottom: 1em;
position: relative;
z-index: 1000;
}
p {
font-size: 16px;
line-height: 1.6em;
margin-bottom: 1.8em;
}
#grey {
width: 100%;
height: 400px;
background: #ccc;
position: relative;
margin-top: 100px;
}
#grey:before {
content: '';
position: absolute;
top: 0;
left: 0;
border-top: 80px solid #fff;
border-right: 80px solid #ccc;
width: 400px;
}
<div id="grey"></div>
<div class="container">
<div class="diagonal">
<h2>Header title</h2>
<p>Yes a CSS diagonal corner is possible</p>
</div>
<div class="diagonal2">
<h2>Header title</h2>
<p>Yes a CSS diagonal corner with background image is possible</p>
</div>
<div class="diagonal3">
<div class="inside">
<h2>Header title</h2>
<p>Yes a CSS diagonal border is even possible with an extra div</p>
</div>
</div>
</div>
We had the problem of different background colors for our cutted elements. And we only wanted upper right und bottom left corner.
body {
background-color: rgba(0,0,0,0.3)
}
.box {
position: relative;
display: block;
background: blue;
text-align: center;
color: white;
padding: 15px;
margin: 50px;
}
.box:before,
.box:after {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: 100%;
border-bottom: 15px solid blue;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
}
.box:before{
border-left: 15px solid blue;
}
.box:after{
border-right: 15px solid blue;
}
.box:after {
bottom: auto;
top: 100%;
border-bottom: none;
border-top: 15px solid blue;
}
/* Active box */
.box.active{
background: white;
color: black;
}
.active:before,
.active:after {
border-bottom: 15px solid white;
}
.active:before{
border-left: 15px solid white;
}
.active:after{
border-right: 15px solid white;
}
.active:after {
border-bottom: none;
border-top: 15px solid white;
}
<div class="box">
Some text goes here. Some text goes here. Some text goes here. Some text goes here.<br/>Some text goes here.<br/>Some text goes here.<br/>Some text goes here.<br/>Some text goes here.<br/>Some text goes here.<br/>
</div>
<div class="box">
Some text goes here.
</div>
<div class="box active">
Some text goes here.
<span class="border-bottom"></span>
</div>
<div class="box">
Some text goes here.
</div>
You can use clip-path, as Stewartside and Sviatoslav Oleksiv mentioned. To make things easy, I created a sass mixin:
#mixin cut-corners ($left-top, $right-top: 0px, $right-bottom: 0px, $left-bottom: 0px) {
clip-path: polygon($left-top 0%, calc(100% - #{$right-top}) 0%, 100% $right-top, 100% calc(100% - #{$right-bottom}), calc(100% - #{$right-bottom}) 100%, $left-bottom 100%, 0% calc(100% - #{$left-bottom}), 0% $left-top);
}
.cut-corners {
#include cut-corners(10px, 0, 25px, 50px);
}
According to Harry's linear-gradient solution (answered Oct 14 '15 at 9:55), it says that opacity background isn't possible, I tried it and yep, it isn't.
But! I found a workaround. No it's not super optimised, but it worked. So here's my solution. Since Harry doesn't use pseudo element, we can achieve this by creating one.
Set position relative to the container and create a pseudo element with the same linear-gradient properties. In other words, just clone it. Then put a transparent background for the container, and lets say a black background for the clone. Put a position absolute on it, a z-index of -1 and an opacity value (ie. 50%). It will do the job. Again it's a workaround and it's not perfect but it works just fine.
.cut-corner {
position: relative;
color: white;
background-repeat: no-repeat;
background-image: linear-gradient(white, white), linear-gradient(white, white), linear-gradient(white, white), linear-gradient(white, white), linear-gradient(to bottom left, transparent calc(50% - 1px), white calc(50% - 1px), white calc(50% + 1px), transparent calc(50% + 1px)), linear-gradient(transparent, transparent), linear-gradient(transparent, transparent);
background-size: 2px 100%, 2px 100%, 100% 2px, 100% 2px, 25px 25px, 100% 100%, 100% 100%;
background-position: 0% 0%, 100% 25px, -25px 0%, 0px 100%, 100% 0%, -25px 0%, 100% 25px;
}
.cut-corner:after {
content: "";
position: absolute;
left: 0;
bottom: 0;
right: 0;
top: 0;
z-index: -1;
opacity: 0.5;
background-repeat: no-repeat;
background-image: linear-gradient(white, white), linear-gradient(white, white), linear-gradient(white, white), linear-gradient(white, white), linear-gradient(to bottom left, transparent calc(50% - 1px), white calc(50% - 1px), white calc(50% + 1px), black calc(50% + 1px)), linear-gradient(black, black), linear-gradient(black, black);
background-size: 2px 100%, 2px 100%, 100% 2px, 100% 2px, 25px 25px, 100% 100%, 100% 100%;
background-position: 0% 0%, 100% 25px, -25px 0%, 0px 100%, 100% 0%, -25px 0%, 100% 25px;
}
/* Just for demo */
div {
padding: 10px;
}
body{
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<div class="cut-corner">
Some content<br>
Some content<br>
Some content<br>
Some content
</div>
With a small edit to Joseph's code, the element does not require a solid background:
div {
height: 300px;
background: url('http://images2.layoutsparks.com/1/190037/serene-nature-scenery-blue.jpg');
position: relative;
}
div:before {
content: '';
position: absolute;
top: 0; right: 0;
border-top: 80px solid white;
border-left: 80px solid rgba(0,0,0,0);
width: 0;
}
http://jsfiddle.net/2bZAW/1921/
This use of 'rgba(0,0,0,0)' allows the inner 'corner' to be invisible
.
You can also edit the 4th parameter 'a', where 0 < a < 1, to have a shadow for more of a 'folded-corner' effect:
http://jsfiddle.net/2bZAW/1922/ (with shadow)
NOTE: RGBA color values are supported in IE9+, Firefox 3+, Chrome, Safari, and in Opera 10+.
by small modification of Joshep's code...You can use this code which seems like right corner folded down as per your requirement.
div {
height: 300px;
background: red;
position: relative;
}
div:before {
content: '';
position: absolute;
top: 0; right: 0;
border-top: 80px solid white;
border-left: 80px solid blue;
width: 0;
}
Another one solution:
html:
<div class="background">
<div class="container">Hello world!</div>
</div>
css:
.background {
position: relative;
width: 50px;
height: 50px;
border-right: 150px solid lightgreen;
border-bottom: 150px solid lightgreen;
border-radius: 10px;
}
.background::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
border: 25px solid lightgreen;
border-top-color: transparent;
border-left-color: transparent;
}
.container {
position: absolute;
padding-left: 25px;
padding-top: 25px;
font-size: 38px;
font-weight: bolder;
}
https://codepen.io/eggofevil/pen/KYaMjV
I recently cut off the top right corner and overlaid the tabs like folders. Complete code noob, so ignore the shitty code, but I did this by combining a square, a triangle, and a rectangle... This may or may not be a new approach, but hopefully, someone finds it helpful.
https://i.stack.imgur.com/qFMRz.png
Here is the HTML:
<!DOCTYPE html>
<html lang ="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="folders">
<div class="container">
<div class="triangleOne">
<p class="folderNames">Home</p>
</div>
<div class="triangleOneCut">
</div>
<div class="triangleOneFill">
</div>
</div>
<div class="container2">
<div class="triangleOne blue">
<p class="folderNames">About</p>
</div>
<div class="triangleOneCut blueCut">
</div>
<div class="triangleOneFill blue">
</div>
</div>
<div class="container3">
<div class="triangleOne green">
<p class="folderNames">Contact</p>
</div>
<div class="triangleOneCut greenCut">
</div>
<div class="triangleOneFill green">
</div>
</div>
</div>
</body>
</html>
Here is the CSS:
.triangleOne {
height: 50px;
width: 40px;
background: red;
border-radius: 5px 0px 0px 5px;
position: absolute;
}
.triangleOneCut {
content: '';
position: absolute;
top: 0; left: 40px;
border-top: 10px solid transparent;
border-left: 10px solid red;
width: 0;
}
.triangleOneFill {
content: '';
position: absolute;
top: 10px; left: 40px;
width: 10px;
height: 40px;
background-color: red;
border-radius: 0px 0px 5px 0px;
}
.container {
position: relative;
height: 50px;
width: 50px;
display: inline-block;
z-index: 3;
}
.container2 {
position: relative;
height: 50px;
width: 50px;
display: inline-block;
left: -10px;
z-index: 2;
}
.container3 {
position: relative;
height: 50px;
width: 50px;
display: inline-block;
left: -20px;
z-index: 1;
}
.blue {
background-color: blue;
}
.green {
background-color: green;
}
.blueCut {
border-left: 10px solid blue;
}
.greenCut {
border-left: 10px solid green;
}
.folders {
width: 160px;
height: 50px;
/* border: 10px solid white; */
margin: auto;
padding-left: 25px;
margin-top: 100px;
}
.folderNames {
text-align: right;
padding-left: 2px;
color: white;
margin-top: 1.5px;
font-family: monospace;
font-size: 6.5px;
border-bottom: double 1.5px white;
}
Here's a solution for if you don't want a solid-color background, i.e. just a border with square-cut corners.
.container {
width: 100px;
height: 100px;
background-color: white;
border: 1px solid black;
position: relative;
}
.border {
position: absolute;
width: 100%;
height: 100%;
}
.border:before {
content: '';
position: absolute;
border-top: 15px solid white;
border-left: 15px solid white;
width: 0;
}
.border:after {
content: '';
position: absolute;
width: 16px;
height: 1px;
background: black;
}
.tl:before { top: -5px; left: -5px; transform: rotate(-45deg); }
.tl:after { top: 5px; left: -3px; transform: rotate(-45deg);}
.tr:before { top: -5px; right: -5px; transform: rotate(45deg); }
.tr:after { top: 5px; right: -3px; transform: rotate(45deg); }
.bl:before { bottom: -5px; left: -5px; transform: rotate(45deg); }
.bl:after { bottom: 5px; left: -3px; transform: rotate(45deg); }
.br:before { bottom: -5px; right: -5px; transform: rotate(-45deg); }
.br:after { bottom: 5px; right: -3px; transform: rotate(-45deg); }
<html>
<body>
<div class="container">
<div class="border tl"></div>
<div class="border tr"></div>
<div class="border bl"></div>
<div class="border br"></div>
</div>
</body>
</html>

CSS scalloped border for image using radial-gradients

I'm trying to use CSS to make a scalloped border for an image using radial-gradients. Here is what I have so far: JS FIDDLE.
As you can see, the top edge of the image has pointy tips, while the bottom edge is rounded. How can I get the pointy tips at the bottom as well? (Like the bottom edge flipped upside down.)
I would appreciate your help!
HTML:
<body>
<div class="top-container">
<p>Top section.</p>
</div>
<div class="container">
<p>Image Section</p>
</div>
<div class="next-container">
<p>Bottom Section</p>
</div>
</body>
CSS:
body {
text-align:center;
background: white;
}
.top-container {
background: white;
}
.container {
position:relative;
background-image: url("http://placekitten.com/1280/120");
height: 100px;
padding-top:40px;
width: 100%;
left: -10px;
}
.container::before {
position:absolute;
bottom: -20px;
left: 0px;
width: 100%;
content:" ";
background:
radial-gradient(circle at 50% 0%, transparent 25%, #000 26%, white 0%);
background-color: transparent ;
background-size:20px 40px;
height:50px;
background-repeat: repeat-x;
background-position: -20px 0px;
}
.container::after {
position:absolute;
top: 0px;
left: 0px;
width: 100%;
content:" ";
background:
radial-gradient(circle at 50% 0%, white 25%, #000 26%, transparent 0%);
background-color: transparent;
background-size:20px 40px;
height:50px;
background-repeat: repeat-x;
background-position: -25px 0px;
}
.next-container {
background: white;
}
Use the same radial-gradient you have on the top, but here you just rotate it 180 degrees
body {
text-align:center;
background: white;
}
.top-container {
background: white;
}
.container {
position:relative;
background-image: url("http://www.rhapsodazzle.com/flowers.jpg");
height: 100px;
padding-top:40px;
width: 100%;
left: -10px;
}
.container::before {
position:absolute;
bottom: 0;/*-20px;*/
transform: rotate(180deg); /* added */
left: 0px;
width: 100%;
content:" ";
background: radial-gradient(circle at 50% 0%, white 25%, #000 26%, transparent 0%);
/*
radial-gradient(circle at 50% 0%, transparent 25%, #000 26%, white 0%);*/
background-color: transparent ;
background-size:20px 40px;
height:50px;
background-repeat: repeat-x;
background-position: -20px 0px;
}
.container::after {
position:absolute;
top: 0px;
left: 0px;
width: 100%;
content:" ";
background:
radial-gradient(circle at 50% 0%, white 25%, #000 26%, transparent 0%);
background-color: transparent;
background-size:20px 40px;
height:50px;
background-repeat: repeat-x;
background-position: -25px 0px;
}
.next-container {
background: white;
}
<body>
<div class="top-container">
<p>Top section.</p>
</div>
<div class="container">
<p>Image Section</p>
</div>
<div class="next-container">
<p>Bottom Section</p>
</div>
</body>
JSfiddle link: jsfiddle.net/oq2ja51g/3/

Angled div background with linear and radial gradient

I am currently using CSS3 to make an div with the left side angled like a trapezium using the following CSS adapted from this jsfiddle:
background:linear-gradient(75deg, transparent 75px, #35753f 76px);
I would like to combine the following CSS background with a radial one, to create the effect shown in the image below. However, when I do this, I lose the angled side. What is the best way to combine these two backgrounds?
Here is the radial background:
background:radial-gradient(circle closest-corner at right center, #337540 0%, #003832 100%);
Here is what it should look like:
Here is a jsfiddle of the below:
.container {
width: 1024px;
margin: 0 auto;
}
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
#top-banner {
position: relative;
}
#top-banner .container {
height: 350px;
}
#top-banner #banner-right {
width: 350px;
height: 350px;
background: -moz-linear-gradient(75deg, transparent 75px, #35753f 76px);
background: -o-linear-gradient(75deg, transparent 75px, #35753f 76px);
background: -webkit-linear-gradient(75deg, transparent 75px, #35753f 76px);
background: linear-gradient(75deg, transparent 75px, #35753f 76px);
position: relative;
float: right;
}
#top-banner #banner-right:after {
content: ".";
display: block;
height: inherit;
width: 5000px;
left: 350px;
top: 0;
position: absolute;
/* IE10 Consumer Preview */
background-image: -ms-radial-gradient(left center, circle closest-corner, #337540 0%, #003832 100%);
/* Mozilla Firefox */
background-image: -moz-radial-gradient(left center, circle closest-corner, #337540 0%, #003832 100%);
/* Opera */
background-image: -o-radial-gradient(left center, circle closest-corner, #337540 0%, #003832 100%);
/* Webkit (Safari/Chrome 10) */
background-image: -webkit-gradient(radial, left center, 0, left center, 140, color-stop(0, #337540), color-stop(1, #003832));
/* Webkit (Chrome 11+) */
background-image: -webkit-radial-gradient(left center, circle closest-corner, #337540 0%, #003832 100%);
/* W3C Markup, IE10 Release Preview */
background-image: ;
z-index: -100;
}
/*#top-banner #banner-right {
width:350px;
height:350px;
background:black;
position:relative;
float: right;
}
#top-banner #banner-right:before {
content:"";
position:absolute;
top:0;
left:0;
width: 0;
height: 0;
border-bottom: 350px solid white;
border-right: 40px solid transparent;
}*/
#top-banner .slider {
float: left;
height: 350px;
width: 100px;
background-color: black;
background-size: cover;
shape-outside: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
<div id="top-banner">
<div class="container clearfix">
<div id="banner-right">
</div>
<div class="slider">
<img src="http://1.bp.blogspot.com/-9aQmrN3-xpQ/TuYsXHQygrI/AAAAAAAAAtw/cEmz4PgEQdQ/s1600/r-NEW-SPECIES-MEKONG-DELTA-huge.jpg" height="350" alt="banner-1" />
</div>
</div>
</div>
Angled div - 2 methods
The angle is created with transform: rotate and not the linear-gradient.
#1 - Rotated :before with translate 3d
In this example, translate3d(0px,0px,1px) is used to eliminate the jagged edge of the rotated element. More information here. I was reminded about this technique from this answer dealing with a similar rendering problem.
As this is a hack that should be used sparingly, their is an alternative way to mask this edge without it in the second example.
Rotate a pseudo element, :before, of the div. This will create our angled edge
The :before gets an appropriate percentage height, width: 100px and is positioned appropriately
The parent div is given overflow: hidden to cut off the background cleanly
Create a second pseudo element, :after, to extend the background to the edge of the viewport.
The gradient background is applied to :after
The :before pseudo element is given a solid background the same color as the edge of the gradient to blend
The :before and :after pseudo elements are given z-index: 1
Elements that will sit above the "background" will need position: relative and z-index: 2 to push them above it. (Like the paragraph in the example below)
Example
The linear-gradient on the body demonstrates that the div can be placed over any background.
body {
background: linear-gradient(#000 0%, #FFF 100%) no-repeat;
margin: 0;
}
div {
position: relative;
height: 350px;
overflow: hidden;
padding-left: 100px;
min-width: 500px;
}
div:before {
content: '';
display: block;
position: absolute;
height: 120%;
width: 90px;
top: -10%;
left: 90px;
background: #003832;
transform: translate3d(0px,0px,1px) rotate(-15deg);
z-index: 1;
}
div:after {
content: '';
display: block;
position: absolute;
height: 120%;
width: 100%;
top: -10%;
left: 135px;
background: radial-gradient(circle closest-corner at 50% 50%, #33753E 0%, #003832 80%);
z-index: 1;
}
p {
color: #FFF;
left: 10px;
position: relative;
z-index: 2;
}
<div>
<p>This is some text</p>
</div>
#2 - Rotated :before and :after without translate 3d
Rotate a pseudo element, :before, of the div
Apply the background to the pseudo element
The pseudo element gets height: 200% and width: 200% and is positioned appropriately
The parent div is given overflow: hidden to cut off the gradient cleanly and the rotated pseudo element becomes the background
A second pseudo element, :after, is used to help mask the jagged edge with a box-shadow (the left edge is jagged at all rotations that are not 45deg increments)
The :before and :after pseudo elements are given z-index: 1
Elements that will sit above the "background" will need position: relative and z-index: 2 to push them above it. (Like the paragraph in the example below)
Example 1
body {
background: linear-gradient(#000 0%, #FFF 100%) no-repeat;
}
div {
position: relative;
width: 500px;
height: 350px;
overflow: hidden;
padding-left: 100px;
}
div:before,
div:after {
content: '';
display: block;
position: absolute;
height: 200%;
width: 200%;
top: -220px;
left: 90px;
background: radial-gradient(circle closest-corner at 20% 50%, #33753E 0%, #003832 100%);
transform: rotate(-15deg);
z-index: 1;
}
div:after {
top: -220px;
left: 92px;
box-shadow: 0 0 2px 2px #003832;
}
p {
color: #FFF;
z-index: 2;
position: relative;
}
<div>
<p>This is some text</p>
</div>
Example 2 - extended
body {
background: linear-gradient(#000 0%, #FFF 100%) no-repeat;
margin: 0;
}
div {
position: relative;
height: 350px;
overflow: hidden;
padding-left: 100px;
max-width: 1600px;
}
div:before,
div:after {
content: '';
display: block;
position: absolute;
height: 300%;
width: 300%;
top: -200%;
left: 90px;
background: radial-gradient(circle closest-corner at 20% 50%, #33753E 0%, #003832 100%);
transform: rotate(-15deg);
z-index: 1;
}
div:after {
left: 92px;
box-shadow: 0 0 2px 2px #003832;
}
p {
color: #FFF;
z-index: 2;
position: relative;
left: 80px;
}
<div>
<p>This is some text</p>
</div>
If you want it to be exactly as you shown on a picture - try :before pseudoclass.
#div_with_background{
position: relative;
background: radial-gradient(circle closest-corner at 60% 50%, #33753E 0%, #003832 100%);
width: 567px;
height: 356px;
}
#div_with_background:before{
content: "";
position: absolute;
top: 0px;
left: 0px;
width: 0;
height: 0;
border-style: solid;
border-width: 356px 0 0px 130px;
border-color: transparent transparent transparent #FFFFFF;
z-index: 1;
}
<div id="div_with_background"></div>

add color to css -webkit-box-reflect instead of image

I want to make to reflection to a solid colour reflection with fade off at the bottom instead of the image itself, is it possible?
http://codepen.io/vincentccw/pen/iGrmq
img{
-webkit-box-reflect: below -2px
-webkit-gradient(linear,
center top,
center bottom,
from(transparent),
to(white));
}
Were you looking for this? Live demo (click).
Sample Markup:
<div class="img-container">
<img src="http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif" />
</div>
JavaScript:
body{
background: black;
}
img {
-webkit-box-reflect: below 0px;
}
.img-container {
display: inline-block;
position: relative;
}
.img-container:after {
content: '';
display: block;
top: 100%;
bottom: -100%;
left: 0;
right: 0;
position: absolute;
background: linear-gradient(to bottom,
transparent 0%,
#FFF 82%
)
}

Nested div masked off by circular container div

I'm trying to figure out if there's a way to do this with CSS: I have a container div with a border-radius of 50% (circular). Inside of that is a rectangular div with a height of 30% positioned at the bottom of the container, and I want to be able to mask that off so that anything outside of the container's rounded border radius doesn't show. How do I accomplish this? Attached is a screenshot of what's currently happening, and this is my code:
<div id="coupon_container">
<div id="meter_container">50c off</div>
</div>
#coupon_container {
position: fixed; right:0; top:0; z-index: 100; color: #fff; width:170px; height: 120px;
#meter_container {
position: absolute; width: 110px; height:110px; .round; background: #greenDk; border:5px solid #fff; left: 60px; overflow: hidden;
.meter_level { width: 100%; height:30%; position: absolute; bottom:0; text-align: center; font-size: 1.6em; background: #limeLt; }
}
}
I really like the gradient solution that bookcasey has posted. However, compatibility may be a drawback as IE9 doesn't support CSS gradients. So another solution would be this one:
demo
The idea is to use a top padding of 70% instead of absolute positioning.
HTML:
<div id="coupon_container">
<div id="meter_container">50c off</div>
</div>
CSS:
#coupon_container {
overflow: hidden;
width: 8em; height: 8em;
border-radius: 50%;
background: green;
}
#meter_container {
margin: 70% 0;
height: 30%;
text-align: center;
background: lime;
}
You can achieve the effect you want using CSS3 gradients:
#coupon_container {
width: 100px;
height: 100px;
border-radius: 100px;
background: -webkit-gradient(linear, 50% 0%, 50% 70, color-stop(100%, #fa8072), color-stop(100%, #ff0000));
background: -webkit-linear-gradient(top, #fa8072 70px, #ff0000 70px);
background: -moz-linear-gradient(top, #fa8072 70px, #ff0000 70px);
background: -o-linear-gradient(top, #fa8072 70px, #ff0000 70px);
background: linear-gradient(top, #fa8072 70px, #ff0000 70px);
position: relative;
}
#meter_container {
width: 100px;
text-align: center;
position: absolute;
bottom: 10px;
}
Demo
I could be totally missing something, but couldn't you just add "overflow: hidden;" to the round element, #coupon_container?

Resources