CSS advanced shape (heart cut out of background) - css

Basically I want to create a shape in CSS only (so no images) that is the opposite of a heart shape. I don't know how to explain it properly so here is an image:
The blue is the background, as you can see, but the shape that I want to create is not a heart, it is the shape of the black rectangle.
If I would have the following shape (THE GRAY NOT THE BLACK)
I could duplicate it and then rotate it, that would give me the shape I am looking for.

Heart shape cut out using box-shadow
Let's create this — the blue is the background color of <body>
The pieces
Feel free to skip directly to the complete demo at the bottom of this answer :)
1 - The rounded corners
The rounded top left and top right corners are created with box-shadow on the two pseudo elements with border-radius: 50% — .heart:before and .heart:after — They form two crescent shapes that look like this:
2 - The angle
The angled shape is created by the box-shadow on .heart. Combined with the two circles, it looks like this:
3 - The filler
We now need to fill in the gaps. This is done by the pseudo elements of the .box-shape container — .shape-box:before and .shape-box:after. The excess is cut-off neatly with overflow: hidden on the .shape-box. Combined with our pieces above, they look like this:
The Complete Example
Combine it all together and we get this nicely cut out heart shape. It is all contained in .shape-box.
body {
background: #00A2F6;
}
.shape-box {
height: 504px;
width: 504px;
position: relative;
margin: 100px;
overflow: hidden;
}
.shape-box:before,
.shape-box:after {
content: '';
display: block;
height: 100px;
width: 120px;
background: #2B2B2B;
transform: rotate(45deg);
left: 190px;
position: absolute;
top: 40px;
}
.shape-box:after {
width: 760px;
height: 750px;
box-shadow: inset 0 0 0 220px #2B2B2B;
top: -150px;
left: -130px;
background: none;
}
.heart {
transform: rotate(45deg);
height: 357px;
width: 356px;
box-shadow: inset 0 0 0 50px #2B2B2B;
position: absolute;
left: 74px;
top: 34px;
}
.heart:before,
.heart:after {
content: '';
display: block;
width: 151px;
height: 151px;
border-radius: 50%;
box-shadow: -40px -15px 0 20px #2B2B2B;
position: absolute;
left: 50px;
top: 157px;
}
.heart:after {
box-shadow: -15px -40px 0 21px #2B2B2B;
left: 156px;
top: 51px;
}
<div class="shape-box">
<div class="heart"></div>
</div>

This can be done with a combination of svg gradients, multiple backgrounds, and a little creative tiling/placement. Sample CSS from my working jsfiddle (without vendor prefixes, i.e. -webkit and -moz):
height: 400px;
width: 400px;
background-image:
radial-gradient(75% 85.5%, circle, transparent 25%, black 26%),
radial-gradient(25% 85.5%, circle, transparent 25%, black 26%),
linear-gradient(225deg, transparent 25%, black 25%),
linear-gradient(135deg, transparent 25%, black 25%);
background-size: 200px 200px;
background-position: top left, top right, bottom left, bottom right;
background-repeat: no-repeat;
This makes a heart-shaped cutout in the middle of a 400px square element. It can be modified to fit whatever size element you want.
Update: here’s a more complex fiddle that uses six gradients instead of four, but looks a bit nicer.

Based on the work that Mark Hubbart did I was able to push this to a slightly more advanced form in this fiddle
This is not 100% complete yet as it will need some media queries to work across more browsers but it does show the start of a much more flexible working for the same goal.
#backgrounder {
z-index: 2;
background-image:
radial-gradient(68% 100%, circle, transparent 48%, white 30%),
radial-gradient(32% 100%, circle, transparent 48%, white 30%),
radial-gradient(110% 1%, circle, transparent 65%, white 30%),
radial-gradient(-8.5% 1%, circle, transparent 65%, white 30%),
linear-gradient(220deg, transparent 41%, white 30%),
linear-gradient(139deg, transparent 41%, white 30%);
background-image:
-webkit-radial-gradient(68% 100%, circle, transparent 48%, white 30%),
-webkit-radial-gradient(32% 100%, circle, transparent 48%, white 30%),
-webkit-radial-gradient(110% 1%, circle, transparent 65%, white 30%),
-webkit-radial-gradient(-8.5% 1%, circle, transparent 65%, white 30%),
linear-gradient(220deg, transparent 41%, white 30%),
linear-gradient(139deg, transparent 41%, white 30%);
background-size: 51% 31%, 50% 31%, 51% 50%, 50% 50%, 51% 51%, 50% 51%;
background-position: top left, top right, 0% 30%, 100% 30%, bottom left, bottom right;
background-repeat: no-repeat;
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
}

Related

White CSS arrow inside div

I'm looking to create this white arrow that goes inside the image with the HTML you can find in the snippet in a pure CSS way, not editing any HTML code.
.foto {
width: 100%;
float: left;
min-height: 215px;
background:
linear-gradient(to bottom right,transparent 50%,#fff 0) bottom right/10% 50% no-repeat, linear-gradient(to bottom left,#fff 50%,transparent 0%) top right/10% 50% no-repeat, url(https://s3.pagegear.co/1/contents/blog/2016/imagen_cachorro_comprimir.jpg) center/cover
}
<div class="foto bg_fix"><img src="https://s3.pagegear.co/1/contents/blog/2016/imagen_cachorro_comprimir.jpg" itemprop="image" width="724" height="230" style="display: none;"></div>
If you do not need to support Edge, you can get away with the clip-path. It's by far the easiest solution to your problem.
You can check the support on CanIUse
Also, amazingly helpful tool for this is Clippy, but don't forget to read about this technique on MDN - CSS clip-path.
.foto {
width: 100%;
float: left;
min-height: 215px;
-webkit-clip-path: polygon(100% 0%, 85% 50%, 100% 100%, 0 100%, 0% 50%, 0 0);
clip-path: polygon(100% 0%, 85% 50%, 100% 100%, 0 100%, 0% 50%, 0 0);
}
/* first value is X, and second value is Y coordinate. Feel free to experiment with percentages according to your needs. */
SOLUTION 2:
Old "trick" which has much much better support => CSS shapes.
You would basically need to create a new element (which is going to be your white triangle) and then put it on top of that image. Here's a sample code for a triangle that you need:
#triangle-left {
width: 0;
height: 0;
border-top: 50px solid transparent;
border-right: 100px solid red; /* red is just for display puproses */
border-bottom: 50px solid transparent;
}
<div id="triangle-left"><div>
Btw, you have both background-image and img tag in your html. Decide which one you want to use, and if you have problem with cropping the image, you may want to look into background position and/or object-fit.
You can correct you gradient like below. You were almost good, simply switch the position of both making the bottom one on the top and the top on on the bottom:
.foto {
min-height: 200px;
background:
linear-gradient(to bottom right,transparent 49.8%,#fff 50%) top right/10% 50%,
linear-gradient(to top right,transparent 49.8%,#fff 50%) bottom right/10% 50%,
url("https://s3.pagegear.co/1/contents/blog/2016/imagen_cachorro_comprimir.jpg") center/cover;
background-repeat:no-repeat;
}
<div class="foto bg_fix" ></div>

How can I draw two lines obliquely with CSS (or SVG)?

I want to create the background image of the attached div element with CSS (or SVG).
div.target {
background-image: linear-gradient(
to right bottom,
transparent 50%,
#00BCD4 50%
);
Background image of the div element I want to create with CSS (or SVG)
We can do this using multiple background image gradients like in the below snippet. The darker shade is assigned as the background color to the element. Then two background image layers created using gradients are placed in such a way that they produce the desired effect. Adding a partially transparent layer of white color above the darker shade will produce a lighter shade.
The background-size of the second layer should be smaller and its background-position should be at the left-bottom side of the element.
div {
height: 200px;
background-color: rgb(20,203,194);
background-image: linear-gradient(to top left, rgba(255,255,255,0.25) 50%, rgba(255,255,255,0) 50%), linear-gradient(to top right, rgba(255,255,255,0.25) 50%, rgba(255,255,255,0) 50%);
background-size: 100% 100%, 50px 50px;
background-position: left top, left bottom;
background-repeat: no-repeat;
}
<div></div>
Angled CSS gradients are known to produce slightly jagged (or uneven or rough) edges and that can be avoided by offsetting the color stop point a bit like in the below demo.
div {
height: 200px;
background-color: rgb(20,203,194);
background-image: linear-gradient(to top left, rgba(255,255,255,0.25) 50%, rgba(255,255,255,0) calc(50% + 1px)), linear-gradient(to top right, rgba(255,255,255,0.25) 50%, rgba(255,255,255,0) calc(50% + 1px));
background-size: 100% 100%, 50px 50px;
background-position: left top, left bottom;
background-repeat: no-repeat;
}
<div></div>
You can do this with :before and :after pseudo elements.
div {
position: relative;
width: 500px;
height: 100px;
background: #0BC7BE;
}
div:after {
position: absolute;
border-style: solid;
border-width: 0 0 100px 500px;
border-color: transparent transparent rgba(255, 255, 255, 0.3) transparent;
right: 0;
top: 0;
content: "";
}
div:before {
position: absolute;
border-style: solid;
border-width: 50px 0 0 70px;
border-color: transparent transparent transparent rgba(255, 255, 255, 0.3);
left: 0;
bottom: 0;
content: "";
}
<div></div>

CSS3 How are zigzagged borders made?

I have been seeing a lot of new websites that have a zigzagged border in between an image and a div. When you open the image in a new tab the zigzag is not there, so it was created either with CSS3 or HTML5. Does anyone know how it is done?
Here are some examples:
http://themeforest.net/item/hungry-a-onepage-html-restaurant-template/full_screen_preview/9855248ref=freshdesignweb
http://designwp.com/yummie/brown/index.html
Wait for them to load.
zig zag borders are made using linear-gradient
50% is the blur
315deg is the rotation of right side
45deg is the rotation of left side
background size is the width and placement of the triangle
div {
width: 100%;
height: 50px;
background-size: 25px 120%;
background-image: linear-gradient(315deg, red 50%, rgba(0, 0, 0, 0) 50%),
linear-gradient(45deg, red 50%, black 50%);
}
<div></div>
you can also change the angle of rotation by changing the deg values
div {
width: 100%;
height: 50px;
background-size: 25px 150%;
background-image: linear-gradient(297deg, red 50%, rgba(0, 0, 0, 0) 50%),
linear-gradient(63deg, red 50%, black 50%);
}
<div></div>
First one is built with repeatable background image, and secound one with :before pseudo element:
.ss-style-top::before {
position: absolute;
content: '';
left: 0;
width: 100%;
height: 30px;
background-size: 25px 100%;
top: 0;
background-image: linear-gradient(315deg, #FFF 50%, transparent 50%),
linear-gradient(45deg, #FFF 50%, transparent 50%);
margin-top: -30px;
z-index: 100;
}
Here is the link of background image from first example: http://www.cssvillain.com/hungry/images/assets/parallax-bottom-alt.png

CSS draw a pie circle that shows progress, with 0% being a transparent circle, and 100% being a opaque circle

I am using background-image and linear-gradient to draw the pie
pie {
width: 5em;
height: 5em;
display: block;
border-radius: 50%;
background-color: green;
float: left;
margin: 1em;
}
.ten {
background-image:
linear-gradient(126deg, transparent 50%, white 50%),
linear-gradient(90deg, white 50%, transparent 50%);
}
Fiddle: http://jsfiddle.net/jonathansampson/7PtEm/
Which works great, but I want to make it so the circle is transparent at 0%, and will fill until 100% will be entirely opaque.
If I set the transparency on pie it just makes the filled parts transparent as well. How can I make it so only part of the circle is transparent?
Thanks in advance!

Making jagged triangle border in CSS

I have a shape with an edge like this in Photoshop:
Is it possible to make the repeated triangles as a border with CSS?
You can use gradients to create a zig-zag patterned background, use the ::after pseud-element to apply it like a border.
.header{
color: white;
background-color: #2B3A48;
text-align: center;
}
.header::after {
content: " ";
display: block;
position: relative;
top: 0px;
left: 0px;
width: 100%;
height: 36px;
background: linear-gradient(#2B3A48 0%, transparent 0%), linear-gradient(135deg, #272220 33.33%, transparent 33.33%) 0 0%, #272220 linear-gradient(45deg, #272220 33.33%, #2B3A48 33.33%) 0 0%;
background-repeat: repeat-x;
background-size: 0px 100%, 9px 27px, 9px 27px;
}
<div class="header"><h1>This is a header</h1></div>
Source: CSS Zigzag Border with a Textured Background
JSFiddle: http://jsfiddle.net/kA4zK/
For future viewers, I found this adaptation of #extramaster's answer to be a little simpler.
It's essentially the same, but it uses one fewer background gradients and allows the backing object (.navbar in my markup) to show through instead of hard-coding the second color into the zig-zag.
JsFiddle: http://jsfiddle.net/861gjx0b/2/
.header {
position: relative;
color: white;
background-color: #2B3A48;
text-align: center;
}
.navbar {
background: #272220;
height: 20px;
}
.header:after {
content: "";
position: absolute;
display: block;
height: 10px;
bottom: -10px;
/* -height */
left: 0;
right: 0;
/* TODO Add browser prefixes */
background: linear-gradient( 45deg, transparent 33.333%, #2B3A48 33.333%, #2B3A48 66.667%, transparent 66.667%), linear-gradient( -45deg, transparent 33.333%, #2B3A48 33.333%, #2B3A48 66.667%, transparent 66.667%);
background-size: 8px 20px;
/* toothSize doubleHeight */
background-position: 0 -10px;
/* horizontalOffset -height */
}
<div class="header">
<h1>This is a header</h1>
</div>
<nav class="navbar"></nav>
Personally, I think clip-path is easier to work with/understand than complex background gradients.
body {
font-family:Roboto,'Open Sans',Helvetica,sans-serif;
}
.container {
background:#ddd;
margin:0 auto;
max-width:800px;
padding:30px;
}
h1:first-child {margin:0;}
.jagged-bottom {
position:relative;
}
.jagged-bottom:after {
background:#ddd;
content:"";
height:2vw;
position:absolute;
top:100%;
left:0;
right:0;
clip-path:polygon(
0 0, 2.5% 100%, 5% 0, 7.5% 100%,
10% 0,12.5% 100%,15% 0, 17.5% 100%,
20% 0,22.5% 100%,25% 0, 27.5% 100%,
30% 0,32.5% 100%,35% 0, 37.5% 100%,
40% 0,42.5% 100%,45% 0, 47.5% 100%,
50% 0,52.5% 100%,55% 0, 57.5% 100%,
60% 0,62.5% 100%,65% 0, 67.5% 100%,
70% 0,72.5% 100%,75% 0, 77.5% 100%,
80% 0,82.5% 100%,85% 0, 87.5% 100%,
90% 0,92.5% 100%,95% 0, 97.5% 100%, 100% 0);
}
<div class="container jagged-bottom">
<h1>Looks Like A Receipt</h1>
<p>Simply adjust the clip path on the pseudo-element if you want more or fewer spikes, and the height if you want them to be taller or shorter.</p>
</div>
There is a border-image property in CSS3.
Maybe you can work it out in a way you want. More here:
https://developer.mozilla.org/en-US/docs/Web/CSS/border-image
Or here
https://www.w3schools.com/cssref/css3_pr_border-image.asp
You can create an individual triangle using CSS quite easily (just tweak border properties). In order for this to work you will need to generate quite a bit of markup yourself. I would recommend against this approach.
Instead you are likely better off using an individual image containing a single triangle (preferably a transparent .png) and then use background-image and background-repeat (repeat-x) properties to bind that to a div (your "border").
Unfortunately there is no yet a straight-forward way to achieve this using pure CSS.

Resources