Clipping Mask to SVG - css

I'm trying to create a menu that when you hover over one of the links, it shows a sliced image in the background. I was able to create something that works only in Chrome using CSS3 clipping masks.
The code to produce these shapes scale with the browser widths (+1 for percentages!) and work excellent except for two things: one being that the mask does not clip the shape I need (refer to the colorful image to see the shape) and it is not viable to use with Firefox and IE.
#music_hover {
z-index: 5;
width: 100%;
height: 100%;
background: red;
-webkit-clip-path: polygon(50% 50%, 100% 50%, 100% 100%, 70% 100%);
clip-path: polygon(50% 50%, 100% 50%, 100% 100%, 70% 100%);
float: right;
position: absolute;
background: url(../music.jpg) bottom right no-repeat;
display: none;
}
Now, to find something supported by more browsers, I have switched to SVG images. I've done this in [CodePen]. My issue with my current solution is that the slices do not "stay together" when the browser is not 1920x1080. The 3 slices in the first row stick to the top while the second row sticks to the bottom creating a white strip in the middle of the page. The slices also do not scale as they have precise points to draw the shape (as opposed to percentages of the clipping mask).
HTML:
<svg version="1.1" id="novel_Position" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 773.685 540.94">
<defs>
<pattern id="novel_BG" patternUnits="userSpaceOnUse" width="100%" height="100%">
<image xlink:href="http://loiseau-noir.com/seb/novel.jpg" x="0" y="0" width="100%" height="100%" />
</pattern>
</defs>
<path d="M420,1.058H0v539.569l696.512,0.313c0.031-72.714,29.516-138.541,77.173-186.197L420,1.058z" fill="red"/>
</svg>
CSS:
#novel_Position {
z-index: 5;
width: 40.5%;
top: 0;
left: 0;
position: fixed;
}
Now if all that isn't clear, the page should function like this:

You can do it without clipping masks, just using transforms and overflow: hidden. and some html structure
html, body {height: 100%;}
.base {
height: 100%;
width: 100%;
border: 1px solid black;
position: relative;
overflow: hidden;
}
.part {
position: absolute;
width: 50%;
height: 50%;
overflow: hidden;
}
.part:after {
content: '';
position: absolute;
width: 100%;
height: 100%;
background-size: cover;
transform-origin: inherit;
}
.NW {
left: 0px;
top: 0px;
transform: skewX(30deg);
transform-origin: bottom right;
}
.NW:after {
transform: skewX(-30deg);
background-image: url("http://placekitten.com/g/200/300");
}
.N {
top: 0px;
right: 0px;
transform: rotate(-60deg) skewX(-30deg);
transform-origin: bottom left;
overflow: hidden;
}
.N:after {
transform: skewX(30deg) rotate(60deg) translateX(-50%) ;
background-image: url("http://placekitten.com/g/600/400");
}
.NE {
right: 0px;
top: 0px;
transform: skewX(-30deg);
transform-origin: bottom left;
}
.NE:after {
transform: skewX(30deg);
background-image: url("http://placekitten.com/g/200/300");
}
.SW {
left: 0px;
bottom: 0px;
transform: skewX(-30deg);
transform-origin: top right;
}
.SW:after {
transform: skewX(30deg);
background-image: url("http://placekitten.com/g/200/300");
}
.S {
bottom: 0px;
right: 0px;
transform: rotate(60deg) skewX(30deg);
transform-origin: top left;
}
.S:after {
transform: skewX(-30deg) rotate(-60deg) translateX(-50%) ;
background-image: url("http://placekitten.com/g/200/300");
}
.SE {
right: 0px;
bottom: 0px;
transform: skewX(30deg);
transform-origin: top left;
}
.SE:after {
transform: skewX(-30deg);
background-image: url("http://placekitten.com/g/200/300");
}
.center {
position: absolute;
width: 20%;
height: 0%;
left: 40%;
top: 50%;
z-index: 10;
}
.roundcenter {
width: 100%;
padding: 50% 0;
border-radius: 50%;
background-color: lightgreen;
margin-top: -50%;
}
<div class="base">
<div class="part NW"></div>
<div class="part N"></div>
<div class="part NE"></div>
<div class="part SW"></div>
<div class="part S"></div>
<div class="part SE"></div>
<div class="center">
<div class="roundcenter">
</div>
</div>
</div>

Related

How to achieve "depth" with a 3d css transform

I am trying to create a "perspective mockup" using CSS. There are a fair amount of tutorials on how to achieve this with 3D layers in Photoshop, but I would like to do it with CSS. Here is an example of what I am trying to achieve:
And here is the code (using the raw image, https://i.imgur.com/foDEYpB.png):
#perspective {
width: 400px;
height: 500px;
position: absolute;
background-image: url("https://i.imgur.com/foDEYpB.png");
background-repeat: no-repeat;
background-size: cover;
top: 50%;
left: 50%;
margin-left: -200px;
margin-top: -250px;
transform: rotate3d(360, 120, -90, 60deg) rotateZ(-30deg);
box-shadow: -15px 15px 20px rgba(0, 0, 0, 0.5);
}
<div id='perspective'></div>
I am pretty close, but am unsure how to achieve the "depth" or "height" where the image looks raised. Zoomed in version of said "depth" where the image is repeated onto the sides:
P.S. if anyone knows the correct name for what I'm referring to as "depth", I'd love to know!
Try adding three type of images to make 3D effects. Use transform property with rotation for images to get the desired result.
Answer reference here.
.perspective {
position: relative;
width: 400px;
height: 500px;
transform-style: preserve-3d;
transition: all 500ms ease-in;
transform: rotateY(20deg) rotateX(60deg) rotateZ(-10deg);
transform: rotateY(15deg) rotateX(50deg) rotateZ(-15deg);
box-shadow: -40px 80px 80px -10px rgba(0, 0, 0, 0.7);
cursor: pointer;
margin-right: 30px;
display: inline-block;
margin-left: 30%;
}
.perspective img {
position: absolute;
top: 0px;
left: 0px;
width: 400px;
height: 500px;
transform: translateZ(16px);
}
.bottom,
.left {
position: absolute;
width: 400px;
height: 500px;
display: block;
transition: all 1s linear;
overflow: hidden;
border-radius: 3px;
transform: translateZ(16px);
filter: brightness(80%)
}
.left {
transform: rotateY(270deg) translateX(-1px);
transform-origin: center left;
width: 18px;
}
.bottom {
transform: rotateX(90deg) translateY(15px) translateZ(-480px);
transform-origin: bottom center;
height: 18px;
}
.bottom img {
transform: rotateX(180deg);
width: 100%;
height: 500px;
left: 0px;
}
<div class="perspective">
<img src="https://i.imgur.com/foDEYpB.png">
<div class="bottom"><img src="https://i.imgur.com/foDEYpB.png"></div>
<div class="left"><img src="https://i.imgur.com/foDEYpB.png"></div>
</div>
Here is a hacky idea using multiple background to simulate such effect. The trick is to add 2 semi-transparent gradients to create the shadow effect then 2 other gradient to cut a small part of the corner to obtain the 3D shape.
The result may not be perfect for all the images:
.wrapper {
display:inline-block;
perspective:1000px;
}
.box {
margin: 50px;
width:200px;
height:200px;
transform: rotate3d(360, 120, -90, 60deg) rotateZ(-30deg);
background:
linear-gradient(to bottom right,transparent 49%,#fff 52%) bottom right/14px 10px,
linear-gradient(to top left,transparent 49%,#fff 52%) top left /10px 14px,
linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5)) 0 0px/10px 100%,
linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5)) 100% 100%/calc(100% - 10px) 10px,
url(https://picsum.photos/id/1061/1000/800) center/cover;
background-repeat:no-repeat;
}
<div class="wrapper" >
<div class="box" >
</div>
</div>
With your image you can have a specific gradient like below:
body {
background:#ccc;
}
.wrapper {
display:inline-block;
perspective:1000px;
}
.box {
margin: 50px;
width:200px;
height:250px;
transform: rotate3d(360, 120, -90, 60deg) rotateZ(-30deg);
background:
linear-gradient(to bottom right,transparent 49%,#ccc 52%) bottom right/16px 10px,
linear-gradient(to top left,transparent 49%,#ccc 52%) top left /10px 12px,
linear-gradient(#efefef,#efefef) 100% 100%/calc(100% - 10px) 10px,
linear-gradient(-226deg,#222428 13px,#ff4946 13px,#ff4946 77px,#592D30 77px,#592D30 100px,#222428 100px,#222428 108px,#efefef 108px,#efefef 161px) 0 0px/10px 100%,
url(https://i.imgur.com/foDEYpB.png) center/cover;
background-repeat:no-repeat;
}
<div class="wrapper">
<div class="box">
</div>
</div>

Line up two elements with a `backdrop-filter: blur()`

When you line up two elements with a backdrop-filter: blur() you (naturally) get an ugly line down the middle. None the less two such elements next to each other might be desirable when you need more complex shapes than a simple square. How can two elements line up without creating such an ugly line?
Warning: This only works in Chrome with experimental web platform features enabled, and possibly in Safari and Edge 17.
div {
position: relative;
width: 400px;
}
.cover {
background: rgba(0,0,0,.1);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
position: absolute;
top: 0px;
bottom: 0px;
width: 50%;
z-index: 1;
}
#left {
left: 0px;
top: 10px;
}
#right {
right: 0px;
bottom: 10px;
}
<div>
<div id="left" class="cover"></div>
<div id="right" class="cover"></div>
<img src="https://www.google.com/google.jpg">
<div>
Since you are already limited to webkit, may be you can take advantage of clip-path. Use a single cover element, and give it the shape that you want.
div {
position: relative;
width: 800px;
}
.cover {
background: rgba(0, 0, 0, .1);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
position: absolute;
top: 0px;
bottom: 0px;
width: 50%;
z-index: 1;
-webkit-clip-path: polygon(50% 10%, 50% 0%, 100% 0, 100% 90%, 50% 90%, 50% 100%, 0 100%, 0% 10%);
}
<div>
<div class="cover"></div>
<img src="https://www.google.com/google.jpg">
</div>
Instead of the clip-path solution provided by #Vals you can use multiple gradient like this:
.container {
position: relative;
display:inline-block;
padding:20px;
}
.container:before {
content:"";
background:
linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1))0 20px/50% 100% no-repeat,
linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1))100% -20px/50% 100% no-repeat;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
position: absolute;
top: 0px;
bottom: 0px;
left:0;
right:0;
z-index: 1;
}
<div class="container">
<img src="https://www.google.com/google.jpg">
<div>

How to implement an pure-CSS flag-shape container?

My target is to implement a pure-CSS flag-shape container like this:
Requirements include:
background-color of parent container is unknown
works for different line-height and font-size settings
Option 1
Use clip-path, but check browser support for this property:
div {
clip-path: polygon(0% 0%, 100% 0%, 85% 50%, 100% 100%, 0% 100%);
background-color: #ff69b4;
/* styles for demo */
padding: 20px;
color: #fff;
}
<div>5 items</div>
Option 2
Use SVG:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<polygon points="0 0, 100 0, 85 50, 100 100, 0 100" fill="#ff69b4" />
</svg>
Option 3
Use absolutely positioned pseudoelements with gradients (to simulate triangles)
div {
background-color: #ff69b4;
margin-right: 50px;
position: relative;
/* styles for demo */
padding: 20px;
color: #fff;
}
/* pseudoelement to simulate triangles */
div:before,
div:after {
content: "";
position: absolute;
top: 0;
left: 100%;
width: 50px;
height: 50%;
background-image: linear-gradient(to left top, transparent 50%, #ff69b4 50%);
}
/* Flip triangle */
div:after {
top: 50%;
transform: scaleY(-1);
}
<div>5 items</div>
Another possible variant would be to use transformed pseudo elements.
Create 2 layers using ::before ad ::after pseudo elements.
Add background-color and place them with position: absolute having 50% height of the parent.
Apply CSS3 skew() transformations to get the flag shape.
Output Image:
Working Demo:
* {box-sizing: border-box;}
body {
background: linear-gradient(green, yellow) no-repeat;
min-height: 100vh;
padding: 10px;
margin: 0;
}
.flag {
padding: 5px 40px 5px 10px;
display: inline-block;
vertical-align: top;
position: relative;
line-height: 40px;
overflow: hidden;
}
.flag:before,
.flag:after {
transform-origin: top right;
transform: skewX(-45deg);
position: absolute;
background: pink;
content: '';
left: -45px;
height: 50%;
z-index: -1;
right: 0;
top: 0;
}
.flag:after {
transform-origin: bottom right;
transform: skewX(45deg);
top: auto;
bottom: 0;
}
<div class="flag">5 Items</div>

background image, linear gradient jagged edged result needs to be smooth edged

I'm trying to make the bottom of an image pointed. I've tried to get this effect by producing two triangles at the bottom. They must be responsive. and after searching all over the internet with a lot of examples that don't work for my requirement this is the best so far I've managed to produce.
body,
html {
height: 100%
}
.image {
width: 1410px;
margin-right: auto;
margin-left: auto;
height: 500px;
overflow: hidden;
position: relative;
}
.pointer {
height: 50px;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
.triangleWrapper {
width: 50%;
height: 50px;
float: left;
}
.lefttriangle {
width: 100%;
height: 10px;
left: 0px;
top: 0px;
background-image: linear-gradient(to right top, #ffffff 50%, transparent 50%);
}
.righttriangle {
width: 100%;
height: 10px;
right: 0px;
top: 0px;
background: linear-gradient(to left top, #ffffff 50%, transparent 50%)
}
<div class="image">
<img src="http://placekitten.com/1410/500">
<div class="pointer">
<div class="triangleWrapper">
<div style="height: 100%;" class="lefttriangle"></div>
</div>
<div class="triangleWrapper">
<div style="height: 100%;" class="righttriangle"></div>
</div>
</div>
</div>
CodePen Demo
It works exactly how I want it to as it is responsive without the need for media queries. BUT it has a jagged edge on the triangle line that isn't 90deg.
How do I get this to produce a smooth line in most if not all modern browsers? I'm not asking for backward compatibility.
Any help is greatly appreciated!
Unfortunately, this always happens when we use angled linear-gradient images and currently the only way to overcome this behavior seems to be to avoid hard-stopping of the colors (that is, don't make the stop point of one color as the start point of the next). Making the second color start a little farther away from the stop point of the first color would kind of create a blurred area and make it look more smoother. This is still not 100% perfect but is better than having jagged edges.
.lefttriangle {
width: 100%;
height: 10px;
left: 0px;
top: 0px;
background-image: linear-gradient(to right top, #ffffff 48%, transparent 50%); /* note the change of stop and start points */
}
.righttriangle {
width: 100%;
height: 10px;
right: 0px;
top: 0px;
background: linear-gradient(to left top, #ffffff 48%, transparent 50%); /* note the change of stop and start points */
}
body,
html {
height: 100%
}
.image {
width: 1410px;
margin-right: auto;
margin-left: auto;
height: 500px;
overflow: hidden;
position: relative;
}
.pointer {
height: 50px;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
.triangleWrapper {
width: 50%;
height: 50px;
float: left;
}
.lefttriangle {
width: 100%;
height: 10px;
left: 0px;
top: 0px;
background-image: linear-gradient(to right top, #ffffff 48%, transparent 50%);
}
.righttriangle {
width: 100%;
height: 10px;
right: 0px;
top: 0px;
background: linear-gradient(to left top, #ffffff 48%, transparent 50%);
}
<div class="image">
<img src="http://placekitten.com/1410/500">
<div class="pointer">
<div class="triangleWrapper">
<div style="height: 100%;" class="lefttriangle"></div>
</div>
<div class="triangleWrapper">
<div style="height: 100%;" class="righttriangle"></div>
</div>
</div>
</div>
Alternate Implementations:
Clip Paths: You can use clip-path feature also to produce a similar effect. The advantage of using clip-path is that it is both responsive and also produces a transparent cut. The SVG based clip-path has better browser support than the CSS version. This is not yet supported in IE though.
body,
html {
height: 100%
}
.image {
width: 1410px;
margin-right: auto;
margin-left: auto;
height: 500px;
overflow: hidden;
position: relative;
}
.css-clip {
-webkit-clip-path: polygon(0% 0%, 0% 90%, 50% 100%, 100% 90%, 100% 0%);
clip-path: polygon(0% 0%, 0% 90%, 50% 100%, 100% 90%, 100% 0%);
}
.svg-clip {
-webkit-clip-path: url(#clipper);
-moz-clip-path: url(#clipper);
clip-path: url(#clipper);
}
<!-- CSS Clip-path - Lower browser support -->
<div class="image css-clip">
<img src="http://placekitten.com/1410/500">
</div>
<!-- SVG Clip-path - Better browser support -->
<svg width="0" height="0">
<defs>
<clipPath clipPathUnits="objectBoundingBox" id="clipper">
<path d="M0,0 0,0.9 0.5,1 1,0.9 1,0z" />
</clipPath>
</defs>
</svg>
<div class="image svg-clip">
<img src="http://placekitten.com/1410/500">
</div>
Using CSS Transform: You could also try using the approach mentioned in this answer. It achieves a pointed effect on the left side but it should be easy to adapt it to create a pointed effect on the bottom side.
body,
html {
height: 100%
}
.image {
width: 1410px;
margin-right: auto;
margin-left: auto;
height: 500px;
overflow: hidden;
position: relative;
}
.top-container,
.bottom-container {
position: absolute;
bottom: 0px;
height: 100%;
width: 50%;
overflow: hidden;
backface-visibility: hidden;
}
.top-container {
left: 0px;
transform-origin: right bottom;
transform: skewY(10deg);
}
.bottom-container {
right: 0px;
transform-origin: left bottom;
transform: skewY(-10deg);
background-position: 0% 100%;
}
.top-container:after,
.bottom-container:after {
position: absolute;
content: '';
height: 100%;
width: 100%;
bottom: -62px; /* tan(10) * (width/2) / 2 */
background: url(http://placekitten.com/1410/500);
background-size: 200% 100%;
}
.top-container:after {
left: 0px;
transform: skewY(-10deg);
}
.bottom-container:after {
right: 0px;
transform: skewY(10deg);
background-position: 100% 0%;
}
<div class="image">
<div class='top-container'></div>
<div class='bottom-container'></div>
</div>
Just found an insanely good solution on codepen using calc(50% - 1px)
https://codepen.io/hellonico/pen/xEYXmL
background: linear-gradient(7deg, currentColor calc(50% - 1px), transparent 50%);
No blur whatsoever, just a smooth edge
EDIT: .. apparently not in Safari?..

Half hexagon shape with one element

I'm trying to replicate the following shape with no success:
I'm guessing I'll need some :before and :after pseudo elements along with the following css:
#pentagon {
position: relative;
width: 78px;
height:50px;
background:#3a93d0;
}
Using Border Method:
You can do it using the below CSS. The shape is obtained by placing a triangle shape at the bottom of the rectangle using :after pseudo element. The triangular part is achieved using border method.
.pentagon {
height: 50px;
width: 78px;
background: #3a93d0;
position: relative;
}
.pentagon:after {
border: 39px solid #3a93d0;
border-top-width: 15px;
border-color: #3a93d0 transparent transparent transparent;
position: absolute;
top: 50px;
content: '';
}
<div class="pentagon"></div>
Using CSS Transforms:
This approach uses rotate, skewX and hence would need a fully CSS3 compliant browser to work properly. The advantage of this approach is that it allows borders to be added around the shape unlike when using border method. The drawback is that it needs additional calculations for the angles.
It is a modified version of the short triangle method mentioned in this CodePen demo by web-tiki.
.pentagon {
position: relative;
height: 50px;
width: 78px;
background: #3a93d0;
}
.pentagon:before {
position: absolute;
content: '';
top: 12px;
left: 0;
width: 46px;
height: 38px;
background: #3a93d0;
transform-origin: 0 100%;
transform: rotate(29deg) skewX(-30deg);
}
.pentagon.bordered {
background: white;
border: 1px solid #3a93d0;
}
.pentagon.bordered:before {
width: 44px;
height: 37px;
background: white;
border: 1px solid #3a93d0;
border-color: transparent #3a93d0 #3a93d0 transparent;
transform: rotate(29deg) skewX(-30deg);
}
/* Just for demo */
.pentagon {
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="pentagon"></div>
<div class="pentagon bordered"></div>
Using CSS Skew Transforms:
This approach uses just skew() (along both X and Y axes) and does not need any complex angle calculations. It just needs the dimensions and position of the pseudo-element to be adjusted as the dimension of the parent changes.
.pentagon {
position: relative;
height: 50px;
width: 78px;
border: 1px solid #3a93d0;
border-bottom: none;
background: aliceblue;
}
.pentagon:before {
position: absolute;
content: '';
top: 10px; /* parent height - child height -1px */
left: -1px;
width: 39px;
height: 39px; /* width of parent/2 */
border-right: 1px solid #3a93d0;
border-bottom: 1px solid #3a93d0;
background: aliceblue;
transform-origin: 0 100%;
transform: matrix(1, 0.414213562373095, -1, 0.41421356237309515, 0, 0);
}
<div class="pentagon">
</div>
The above snippet uses matrix transform because as per MDN, the skew(x, y) is removed and should not be used anymore. The Matrix Resolutions site can be used to obtain the equivalent matrix function. The matrix function for rotate(45deg) skew(-22.5deg, -22.5deg) is
matrix(1, 0.414213562373095, -1, 0.41421356237309515, 0, 0).
Using Clip Path:
Here is another approach to creating the pentagon shape with clip-path. Either a pure CSS clip-path or one with inline SVG can be used depending on required browser support. CSS clip-path is supported only by Webkit browsers at present.
IE (all versions) do not support either the CSS or the SVG clip-path.
.pentagon {
position: relative;
width: 75px;
height: calc(75px / 1.414);
background: #3a93d0;
}
.pentagon.css {
-webkit-clip-path: polygon(0% 0%, 0% 66%, 50% 100%, 100% 66%, 100% 0%);
clip-path: polygon(0% 0%, 0% 66%, 50% 100%, 100% 66%, 100% 0%);
}
.pentagon.svg {
-webkit-clip-path: url(#clipper);
clip-path: url(#clipper);
}
.pentagon.bordered:after {
position: absolute;
content: '';
height: calc(100% - 2px);
width: calc(100% - 2px);
left: 1px;
top: 1px;
background: white;
}
.pentagon.css.bordered:after {
-webkit-clip-path: polygon(0% 0%, 0% 66%, 50% 100%, 100% 66%, 100% 0%);
clip-path: polygon(0% 0%, 0% 66%, 50% 100%, 100% 66%, 100% 0%);
}
.pentagon.svg.bordered:after {
-webkit-clip-path: url(#clipper);
clip-path: url(#clipper);
}
/* Just for demo */
.pentagon {
margin: 10px;
}
<svg width="0" height="0">
<defs>
<clipPath id="clipper" clipPathUnits="objectBoundingBox">
<path d="M0,0 0,0.66 0.5,1 1,0.66 1,0z" />
</clipPath>
</defs>
</svg>
<h3>CSS Clip Path</h3>
<div class="pentagon css"></div>
<div class="pentagon bordered css"></div>
<h3>SVG Clip Path</h3>
<div class="pentagon svg"></div>
<div class="pentagon bordered svg"></div>
You can try an alternate approach using transform scaleX and rotate: 45deg;. This makes it very easy to create the bottom part of the shape.
transform: scaleX() rotate(45deg);
Working
*sorry for bad quality gif! :(
Sans border:
Fiddle
#pent{
height: 50px;
width: 100px;
position: relative;
background-color: deepskyblue;
}
#pent:before{
content: '';
position: absolute;
bottom: 0;
left: 0;
width:45px;
height:45px;
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
transform-origin: 0 100%;
-webkit-transform: scaleX(1.57) rotate(45deg);
-moz-transform: scaleX(1.57) rotate(45deg);
-ms-transform: scaleX(1.57) rotate(45deg);
transform: scaleX(1.57) rotate(45deg);
background-color: deepskyblue;
}
<div id="pent"></div>
With border :
Fiddle
#pent{
height: 50px;
width: 100px;
position: relative;
border: 1px solid black;
border-bottom: 0;
}
#pent:before{
content: '';
position: absolute;
bottom: 0;
left: -1px;
width:45px;
height:45px;
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
transform-origin: 0 100%;
-webkit-transform: scaleX(1.57) rotate(45deg);
-moz-transform: scaleX(1.57) rotate(45deg);
-ms-transform: scaleX(1.57) rotate(45deg);
transform: scaleX(1.57) rotate(45deg);
border: 1px solid black;
border-top: 0;
border-left: 0;
}
<div id="pent"></div>
See a demo - basically it uses css triangles and a pseudo element to give a place for the triangle.
.shape {
position: relative;
width: 78px;
height:30px;
background:#3a93d0;
}
.shape:after {
content: '';
display: block;
position: absolute;
top: 100%;
width: 0;
height: 0;
border-style: solid;
border-width: 25px 39px 0 39px;
border-color: #3a93d0 transparent transparent transparent;
}
<style>
#pentagon
{
position: relative;
width: 54px;
border-width: 40px 18px 0;
border-style: solid;
border-color: #3a93d0;
}
#pentagon:after {
border-color: #3a93d0 transparent transparent;
border-style: solid;
border-width: 21px 45px 0;
content: "";
height: 0;
left: -17px;
position: absolute;
top: 0;
width: 0;
}
</style>
if you dont want to use css3 you can do it with css
only problem is this implementation is not responsive. :(
<pre>
<div class="moregrey"></div>
<div class="arrowdown"></div>
.moregrey
{
width: 1000px;
height: 30px;
background: #3f3f40;
}
.arrowdown
{
border-top:50px solid #3f3f40;
border-left:500px solid transparent;
border-bottom:500px solid transparent;
border-right:500px solid transparent;
display:block;
width:0px;
height:10px;
}
</pre>
<pre>
http://jsfiddle.net/jmqoj5nh/1/
</pre>

Resources