Content/Number inside a shape symbol - html

I want to put a content inside star shape symbol. Finding it difficult to use only css and not an svg. I tried something like this: https://css-tricks.com/examples/ShapesOfCSS/ but it does not work.
One way is using an SVG's but they are hard on responsiveness, as I need to have additional jquery/js functions there.
So wondering is there any other ways of achieving this.

You can use clip path (Clippy is a good generator) to create the star, and align the text vertically using a pseudo element.
Note: Clip path on DOM elements is currently supported only by Chrome, Firefox, and their mobile versions.
.star {
height: 100px;
width: 100px;
-webkit-clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
text-align: center;
background: red;
color: white;
}
.star::before {
display: inline-block;
height: 100%;
background: blue;
vertical-align: middle;
content: '';
}
<div class="star">100</div>

You could wrap the star in a container with some flexbox properties. Add your content and use position: absolute to center it...
code for star from css tricks
.wrapper {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
height: 100vh;
}
#star-five {
margin: 50px 0;
position: relative;
display: block;
color: red;
width: 0px;
height: 0px;
border-right: 100px solid transparent;
border-bottom: 70px solid red;
border-left: 100px solid transparent;
-moz-transform: rotate(35deg);
-webkit-transform: rotate(35deg);
-ms-transform: rotate(35deg);
-o-transform: rotate(35deg);
}
#star-five:before {
border-bottom: 80px solid red;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
position: absolute;
height: 0;
width: 0;
top: -45px;
left: -65px;
display: block;
content: '';
-webkit-transform: rotate(-35deg);
-moz-transform: rotate(-35deg);
-ms-transform: rotate(-35deg);
-o-transform: rotate(-35deg);
}
#star-five:after {
position: absolute;
display: block;
color: red;
top: 3px;
left: -105px;
width: 0px;
height: 0px;
border-right: 100px solid transparent;
border-bottom: 70px solid red;
border-left: 100px solid transparent;
-webkit-transform: rotate(-70deg);
-moz-transform: rotate(-70deg);
-ms-transform: rotate(-70deg);
-o-transform: rotate(-70deg);
content: '';
}
.wrapper span {
position: absolute;
color: white;
font-size: 48px;
}
<div class="wrapper">
<div id="star-five"></div>
<span>2</span>
</div>

<html>
<head>
<style>
#star-five {
margin: 50px 0;
position: relative;
display: block;
color: red;
width: 0px;
height: 0px;
border-right: 100px solid transparent;
border-bottom: 70px solid red;
border-left: 100px solid transparent;
-moz-transform: rotate(35deg);
-webkit-transform: rotate(35deg);
-ms-transform: rotate(35deg);
-o-transform: rotate(35deg);
}
#star-five:before {
border-bottom: 80px solid red;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
position: absolute;
height: 0;
width: 0;
top: -45px;
left: -65px;
display: block;
content: '';
-webkit-transform: rotate(-35deg);
-moz-transform: rotate(-35deg);
-ms-transform: rotate(-35deg);
-o-transform: rotate(-35deg);
}
#star-five:after {
position: absolute;
display: block;
color: red;
top: 3px;
left: -105px;
width: 0px;
height: 0px;
border-right: 100px solid transparent;
border-bottom: 70px solid red;
border-left: 100px solid transparent;
-webkit-transform: rotate(-70deg);
-moz-transform: rotate(-70deg);
-ms-transform: rotate(-70deg);
-o-transform: rotate(-70deg);
content: '';
}
#item {
margin-top: -75px;
left: 75px;
position: absolute;
}
</style>
</head>
<body>
<div>
<div id="star-five">
</div>
<div id="item">
ITEM
</div>
</div>
</body>
</html>
This works just change position and manipulate margin!

<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
.star{position:relative; display:inline-block;}
.star i{font-size:68px;}
.star-content{position: absolute;top: 37%; left: 37%; z-index: 999999; text-align: center; }
.star-content span{color: #fff;}
</style>
</head>
<body>
<div class="star">
<i class="fa fa-star" aria-hidden="true"></i>
<div class="star-content">
<span>01</span>
</div>
</div>
</body>
</html>

You can set your star as Unicode character and use absolute positioning to move number inside star. There you can set CSS properties color and font-size to use color and font-size.
.star {
font-size: 75px;
color: cornflowerblue;
position: relative;
display: inline-block;
}
.star:after {
content: "1";
font-size: 16px;
color: white;
display: inline-block;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -20%);
}
<div class="star">★</div>

Related

Styling a custom arrow using css

I am trying to style this arrow but i have been unable to get this exact style.
here is image of what i want to achieve
here is image of what i am getting
HTML Code:
<div className="arrow-div">
<p>2. Summary</p>
</div>
CSS Code:
.arrow-div {
width: 209px;
height: 56px;
display: inline-flex;
margin: 54px 10px;
border: 1px solid #d2d6dc;
clip-path: polygon(75% 0%, 84% 50%, 75% 100%, 0% 100%, 9% 53%, 0% 0%);
padding: 18px 3px 18px 32px;
}
.arrow-div {
height: 50px;
width: 100px;
padding-left: 20px;
display: inline-block;
position: relative;
margin-left: 20px;
}
.arrow-div:before,
.arrow-div:after {
content: '';
left: -15px;
position: absolute;
height: 23px;
width: 132px;
border-left: 2px solid #0f3c80;
border-right: 2px solid #0f3c80;
}
.arrow-div:before {
border-top: 2px solid #0f3c80;
transform-origin: 0% 0%;
transform: skewX(30deg);
top: 0;
}
.arrow-div:after {
border-bottom: 2px solid #0f3c80;
transform-origin: 0% 100%;
transform: skewX(-30deg);
bottom: 0;
}
p {
color: #0f3c80;
<div class="arrow-div">
<p>2. Summary</p>
</div>

CSS - Oblique border without filling

I've a div and I need a border with the left side oblique, but I'm finding only solutions that have the element filled with color.
I need only the border, like this picture:
How can I do this?
My actual code:
HTML
<div class="arrow">
<span id="time">30 mins</span>
<img src="assets/up_arrow.png" />
</div>
CSS
.arrow {
display: inline-block;
text-align: right;
text-decoration: none;
margin-left: 35%;
padding: 5px 0 5px 0;
border-style: solid;
border-width: 1px 0 1px 0;
border-color: #929A9D transparent #929A9D transparent;
}
.arrow > img {
vertical-align: middle;
width: 12px;
height: 12px;
}
TRY THIS DEMO
HTML & CSS
#a {
position: relative;
width: 120px;
padding: 10px 20px;
font-size: 20px;
position: relative;
margin-left:50px;
color: #2E8DEF;
border: 3px solid #2E8DEF;
border-left:0;
}
#a:before {
content: " ";
position: absolute;
display: block;
width: 50%;
height: 100%;
top: -3px;
left: -30px;
z-index: -1;
border:3px solid #2E8DEF;
border-right: 0px;
transform-origin: bottom left;
-ms-transform: skew(-30deg, 0deg);
-webkit-transform: skew(-30deg, 0deg);
transform: skew(-30deg, 0deg);
}
<div id="a">
Hello
</div>
I have created the shape using border and before pseudo element. Hope this will help.
.ClassicBorder {
width: 200px;
padding: 4px 0;
border: 2px solid #999;
position: relative;
margin-left: 9px;
text-align: center;
font-size: 25px;
}
.ClassicBorder:before {
height: 36px;
width: 40px;
border: 2px solid #999;
content: '';
position: absolute;
border-right: 0px;
border-top: 0px;
transform: skew(340deg);
-webkit-transform: skew(340deg);
-moz-transform: skew(340deg);
background: #fff;
left: -9px;
top:0px;
}
<div class="ClassicBorder">
30 Mins >
</div>
I found a more elegant way, that's more easier to maintain, based on this answer: https://stackoverflow.com/a/24691352/5287860.
New code:
.row {
display: block;
overflow: hidden;
background: linear-gradient(to right, #fff, transparent, #fff, #fff);
}
.arrow {
display: inline-block;
text-align: center;
text-decoration: none;
padding: 5px 0 5px 5px;
border-style: solid;
border-width: 1px 0px 1px 1px;
border-color: #929A9D transparent #929A9D #929A9D;
transform: skewX(-20deg);
-ms-transform: skewX(-20deg);
-webkit-transform: skewX(-20deg);
width: 100px;
}
.arrow > div {
display: inline-block;
text-decoration: none;
transform: skewX(20deg);
-ms-transform: skewX(20deg);
-webkit-transform: skewX(20deg);
}
.arrow > img {
vertical-align: middle;
width: 12px;
height: 12px;
text-decoration: none;
transform: skewX(20deg);
-ms-transform: skewX(20deg);
-webkit-transform: skewX(20deg);
}
<div class="row">
<div class="arrow">
<div><span id="">30 mins</span></div>
<img src="assets/up_arrow.png" />
</div>
</div>

CSS Arrows with borders

I found this codepen demo which almost does what I need (http://codepen.io/web-tiki/pen/EaKPMK).
HTML:
<div class="wrap">
<div class="arrow"></div>
</div>
CSS:
.wrap {
position: relative;
height:150px;
overflow: hidden;
width: 70%;
margin: 0 auto;
}
.wrap img {
width: 100%;
height: auto;
display: block;
}
.arrow {
position: absolute;
bottom: 0;
width: 100%;
padding-bottom:3%;
background-color: rgba(0, 0, 0, 0.8);
}
.arrow:before, .arrow:after {
content:'';
position: absolute;
bottom: 100%;
width: 100%;
padding-bottom:inherit;
background-color: inherit;
}
.arrow:before {
right: 20%;
-ms-transform-origin: 100% 100%;
-webkit-transform-origin: 100% 100%;
transform-origin: 100% 100%;
-ms-transform: skewX(45deg);
-webkit-transform: skewX(45deg);
transform: skewX(75deg);
}
.arrow:after {
left: 80%;
-ms-transform-origin: 0 100%;
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
-ms-transform: skewX(-45deg);
-webkit-transform: skewX(-45deg);
transform: skewX(-75deg);
}
The only thing that's missing is, that I actually need a border around the box. When I add borders to the pseudo elements, the skewed part doesn't produce a closed line.
.arrow:before {
right: 20%;
-ms-transform-origin: 100% 100%;
-webkit-transform-origin: 100% 100%;
transform-origin: 100% 100%;
-ms-transform: skewX(45deg);
-webkit-transform: skewX(45deg);
transform: skewX(75deg);
border-top: 4px solid #df0000;
border-right: 30px solid #df0000;
}
.arrow:after {
left: 80%;
-ms-transform-origin: 0 100%;
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
-ms-transform: skewX(-45deg);
-webkit-transform: skewX(-45deg);
transform: skewX(-75deg);
border-top: 4px solid #df0000;
border-left: 30px solid #df0000;
}
Any Ideas how to make this work?
This is my solution, although it inserts a new element: <div class="arrow-head">
.wrap {
position: relative;
height:150px;
overflow: hidden;
width: 70%;
margin: 0 auto;
}
.wrap img {
width: 100%;
height: auto;
display: block;
}
.arrow {
position: absolute;
bottom: 0;
width: 100%;
padding-bottom:3%;
background-color: rgba(0, 0, 0, 0.8);
}
.arrow:before, .arrow:after {
content:'';
position: absolute;
bottom: 100%;
width: 100%;
padding-bottom:inherit;
background-color: inherit;
}
.arrow:before {
right: 20%;
-ms-transform-origin: 100% 100%;
-webkit-transform-origin: 100% 100%;
transform-origin: 100% 100%;
-ms-transform: skewX(45deg);
-webkit-transform: skewX(45deg);
transform: skewX(75deg);
border-top: 4px solid #df0000;
border-right: 30px solid #df0000;
}
.arrow:after {
left: 80%;
-ms-transform-origin: 0 100%;
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
-ms-transform: skewX(-45deg);
-webkit-transform: skewX(-45deg);
transform: skewX(-75deg);
border-top: 4px solid #df0000;
border-left: 30px solid #df0000;
}
.arrow-head {
position: absolute;
right: -moz-calc(20% - 30px);
right: webkit-calc(20% - 30px);
right: -o-calc(20% - 30px);
right: calc(20% - 30px);
width: 0;
height: 0;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
border-top: 8px solid #df0000;
}
<div class="wrap">
<div class="arrow">
<div class="arrow-head">
</div>
</div>
</div>
here is one way.i think this is what you are looking for
.arrow:before {
right: 20%;
-ms-transform-origin: 100% 100%;
-webkit-transform-origin: 100% 100%;
transform-origin: 100% 70%;
-ms-transform: skewX(45deg);
-webkit-transform: skewX(45deg);
transform: skewX(75deg);
border-top: 4px solid #df0000;
border-right: 30px solid #df0000;
}
.arrow:after {
left: 80%;
-ms-transform-origin: 0 100%;
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
-ms-transform: skewX(-45deg);
-webkit-transform: skewX(-45deg);
transform: skewX(-75deg);
border-top: 4px solid #df0000;
border-left: 30px solid #df0000;
}
you need to decrease the value of the pseudo elements like-
.arrow:after {left:49%}
so your code will be look like-
.wrap {
position: relative;
height:150px;
overflow: hidden;
width: 70%;
margin: 0 auto;
}
.wrap img {
width: 100%;
height: auto;
display: block;
}
.arrow {
position: absolute;
bottom: 0;
width: 100%;
padding-bottom:3%;
background-color: rgba(0, 0, 0, 0.8);
}
.arrow:before, .arrow:after {
content:'';
position: absolute;
bottom: 100%;
width: 50%;
padding-bottom:inherit;
background-color: inherit;
}
.arrow:before {
right: 50%;
-ms-transform-origin: 100% 100%;
-webkit-transform-origin: 100% 100%;
transform-origin: 100% 100%;
-ms-transform: skewX(45deg);
-webkit-transform: skewX(45deg);
transform: skewX(45deg);
border-right:10px solid red;
border-top:10px solid red;
}
.arrow:after {
left: 49%;
-ms-transform-origin: 0 100%;
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
-ms-transform: skewX(-45deg);
-webkit-transform: skewX(-45deg);
transform: skewX(-45deg);
border-left:10px solid red;
border-top:10px solid red;
}
it will look like this -
I came up with this solution:
html:
<div class="bar left"></div><!--
--><div class="arrow-outer">
<div class="square left"></div>
<div class="square right"></div>
<div class="border left"></div>
<div class="border right"></div>
</div><!--
--><div class="bar right"></div>
css:
*{
box-sizing: border-box;
}
.bar{
position: relative;
vertical-align: top;
width: 200px;
height: 35px;
display: inline-block;
background-color: #dfdfdf;
border-top: 4px solid #ff0000;
}
.arrow-outer{
display: inline-block;
vertical-align: top;
width: 100px;
height: 35px;
position: relative;
overflow: hidden;
}
.square{
position: absolute;
width: 100px;
height: 100px;
top: 0;
background-color: #dfdfdf;
}
.square.left{
transform-origin:left top;
left: 0;
transform: rotate(30deg);
}
.square.right{
transform-origin:right top;
right: 0;
transform: rotate(-30deg);
}
.border{
width: 58px;
height: 4px;
background-color: #ff0000;
position: absolute;
top: 0;
}
.border.left{
transform-origin:left top;
left: 0;
transform: rotate(30deg) skewX(30deg);
}
.border.right{
transform-origin:right top;
right: 0;
transform: rotate(-30deg) skewX(-30deg);
}
Here's the codepen:
http://codepen.io/swissdoode/pen/OpzEaJ
The only problem is, that the «fake» border doesn't really line up to the other borders because of the rotate and skewX. It's barely visible, though...
Thoughts?

Badge isn't a perfect triangle

I wrote a code to create a triangular badge. It is almost working, only lower end is kinda cut off.
Here is my code:
span {
border: 1px solid #999;
border-radius: 5px;
display: inline-block;
padding: 3px 8px;
text-decoration: none;
}
.newBadge {
border-right: 50px solid transparent !important;
border-top: 50px solid #777 !important;
height: 41px !important;
left: 0px;
position: absolute;
top: 0px;
}
.badgeText {
color: #fff;
height: 90px;
left: 0;
position: absolute;
top: 0;
width: 100px;
height: 90px;
}
.badgeText strong {
display: block;
height: 100%;
left: 37px;
position: relative;
-webkit-transform: rotate(-45deg) translate(0, -25%);
-moz-transform: rotate(-45deg) translate(0, -25%);
-ms-transform: rotate(-45deg) translate(0, -25%);
-o-transform: rotate(-45deg) translate(0, -25%);
transform: rotate(-45deg) translate(0px, -25%);
width: 100%;
font-size: 12px;
bottom: 10px;
}
<span class="newBadge"></span>
<span class="badgeText">
<strong>Text</strong>
</span>
How do I fix the lower end of the triangle?
I had to tweak .newBadge a little:
span {
border: 1px solid #999;
border-radius: 5px;
display: inline-block;
padding: 3px 8px;
text-decoration: none;
}
.newBadge {
border-right: 80px solid transparent !important;
border-top: 70px solid #777 !important;
height: 41px !important;
left: -20px;
position: absolute;
top: 0px;
border-bottom:none;
}
.badgeText {
color: #fff;
height: 90px;
left: 0;
position: absolute;
top: 0;
width: 100px;
height: 90px;
}
.badgeText strong {
display: block;
height: 100%;
left: 37px;
position: relative;
-webkit-transform: rotate(-45deg) translate(0, -25%);
-moz-transform: rotate(-45deg) translate(0, -25%);
-ms-transform: rotate(-45deg) translate(0, -25%);
-o-transform: rotate(-45deg) translate(0, -25%);
transform: rotate(-45deg) translate(0px, -25%);
width: 100%;
font-size: 12px;
bottom:10px;
}
<span class="newBadge"></span>
<span class="badgeText">
<strong>Text</strong>
</span>
So, moving to the left side, little more, and increasing borders, did the trick, it seems? Also, border-bottom is set to none, because it is inherited from span...
Also, not sure, but if you can work with fixed dimensions of badge, i would suggest much easier (cleaner) HTML/CSS: https://jsfiddle.net/9o00a553/
div {
border: 1px solid #999;
border-radius: 5px;
display: inline-block;
padding: 3px 8px;
text-decoration: none;
width:100px;
height:100px;
position:relative;
overflow:hidden;
margin:50px;
}
div:before {
content:"";
color:white;
transform: rotate(-45deg);
position:absolute;
background:red;
width:100%;
height:100%;
left:-50%;
top:-50%;
}
span {
transform: rotate(-45deg);
color:white;
position:absolute;
z-index:3;
left:12px;
top:20px;
}
<div>
<span class="text">text</span>
</div>
Short answer: Remove the height and padding on the badge, and use the left and bottom borders as well. The changed style for .newBadge will be like this:
.newBadge {
padding: 0;
border-top: 33px solid #777 !important;
border-bottom: 33px solid transparent !important;
border-left: 33px solid #777 !important;
border-right: 33px solid transparent !important;
height: 0 !important;
left: 0px;
position: absolute;
top: 0px;
}
On (very) close inspection, you might notice that the right and bottom corners look a little cut-off; this is due to the border-radius. Setting border-top-right-radius and border-bottom-left-radius to 0 will make those nice and sharp.
Longer answer: The cut-off on the bottom corner is being caused mainly by the padding, and also a little bit from the browser rendering something due to the border-radius and the transparent border color (I couldn't tell you why that is). I don't think there's a clean and reliable way to completely get rid of those artifacts.
Instead, rearrange the parts of the border to more directly create the triangle you want. Since the two legs are the top and left, color the top and left parts of the border, then use the opposite sides uncolored to square it up. Setting all the border-widths the same will keep it even. The width of each border will be half of the side length — since the original border width was 50, and the left and right padding were each 8, the new border width is (50 + 8 + 8) / 2 == 33.
The snippet shows a comparison of the original and changed results. Change the colors of each border fragment to see what each one contributes.
span {
border: 1px solid #999;
border-radius: 5px;
display: inline-block;
padding: 3px 8px;
text-decoration: none;
}
.newBadge {
border-right: 50px solid transparent !important;
border-top: 50px solid #777 !important;
height: 41px !important;
left: 0px;
position: absolute;
top: 0px;
}
#new .newBadge {
/* padding and height should be 0, or they will interfere with the triangle */
padding: 0;
height: 0 !important;
/* Since the triangle is top and left, color those parts of the border, and use the opposite sides uncolored with the same dimensions to make the triangle perfect */
border-top: 33px solid #777 !important;
border-bottom: 33px solid transparent !important;
border-left: 33px solid #777 !important;
border-right: 33px solid transparent !important;
}
.badgeText {
color: #fff;
height: 90px;
left: 0;
position: absolute;
top: 0;
width: 100px;
height: 90px;
}
.badgeText strong {
display: block;
height: 100%;
left: 37px;
position: relative;
-webkit-transform: rotate(-45deg) translate(0, -25%);
-moz-transform: rotate(-45deg) translate(0, -25%);
-ms-transform: rotate(-45deg) translate(0, -25%);
-o-transform: rotate(-45deg) translate(0, -25%);
transform: rotate(-45deg) translate(0px, -25%);
width: 100%;
font-size: 12px;
bottom: 10px;
}
/* The rest is just to get the side-by-side divs for comparison. */
div {
position: relative;
width: 140px;
float: left;
margin-top: 1.2em;
}
div::before {
display: block;
position: relative;
top: -1.2em;
}
#old::before {
content: "Old:";
}
#new::before {
content: "New:";
}
<div id="old">
<span class="newBadge"></span>
<span class="badgeText">
<strong>Text</strong>
</span>
</div>
<div id="new">
<span class="newBadge"></span>
<span class="badgeText">
<strong>Text</strong>
</span>
</div>

Proper way to create CSS3 Pentagon [duplicate]

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>