4

I am trying to take this css Octagon and give it a solid red border. However, when i add the border it only works on portion of the shape. Does anyone have a solution for this?

enter image description here

Here is a JS FIDDLE

HTML

<div class='octagonWrap'>
      <div class='octagon'></div>
  </div>

CSS

.octagonWrap{
        width:200px;
        height:200px;
        float: left;
        position: relative;
        }
    .octagon{
        position: absolute;
        top: 0; right: 0; bottom: 0; left: 0;
        overflow: hidden;
        }
    .octagon:before {
        position: absolute;
        top: 0; right: 0; bottom: 0; left: 0;
        transform: rotate(45deg);
        background: #777;
        content: '';
        border: 3px solid red;
        }
Patrick
  • 800
  • 3
  • 10
  • 36

7 Answers7

10

You can modify your own code to work with this. Right now, you have rules for .octagon that should be for .octagon-wrapper, and rules for .octagon::before that should be for .octagon. Just shift the CSS rules and have them apply to their parents, while changing the border property of .octagon::before to inherit from .octagon.

.octagonWrap {
    width:200px;
    height:200px;
    float: left;
    position: relative;
    overflow: hidden;
}
.octagon {
    position: absolute;
    top: 0; right: 0; bottom: 0; left: 0;
    overflow: hidden;
    transform: rotate(45deg);
    background: #777;
    border: 3px solid red;
}
.octagon:before {
    position: absolute;
    /* There needs to be a negative value here to cancel
     * out the width of the border. It's currently -3px,
     * but if the border were 5px, then it'd be -5px.
     */
    top: -3px; right: -3px; bottom: -3px; left: -3px;
    transform: rotate(45deg);
    content: '';
    border: inherit;
}
<div class='octagonWrap'>
    <div class='octagon'></div>
</div>
jperezov
  • 3,041
  • 1
  • 20
  • 36
9

SVG solution

I do not know if using svg is an option,
If it is here is how simple it is done.

<svg viewBox="0 0 75 75" width="200px">
  <path d="m5,22 18,-18 28,0 18,18 0,28 -18,18, -28,0 -18,-18z" stroke="red" stroke-width="2" fill="black" />
</svg>
Persijn
  • 14,624
  • 3
  • 43
  • 72
  • Hello! This works great actually! Do you have a path for an 8pointer star? Also where do you find these "cords" ? – Patrick Jan 06 '16 at 20:49
  • 1
    the "cords" are created by hand by me, if you want to createshapes with curves and what not take a look here: [Path mdn](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths) – Persijn Jan 07 '16 at 09:46
4

You can do that very effectively with clip-path

.octagonWrap {
  background: red;
  width: 200px;
  height: 200px;
  position: absolute;
  -webkit-clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
  clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
}

.octagon {
  position: relative;
  background: gray;
  width: 190px;
  height: 190px;
  top: 5px;
  left: 5px;
  -webkit-clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
  clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
}
<div class="octagonWrap">
  <div class='octagon'></div>
</div>
Hil
  • 329
  • 4
  • 10
3

You could use an online calculator (or calculate it manually) to compute the size in which the ratio of the side, and overall height needs to be.

Then by using some pseudos and a span element, you could create this shape via:

.oct {
  height: 241px;
  width: 100px;
  background: none;
  position: relative;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  border-top: 10px solid tomato;
  border-bottom: 10px solid tomato;
  margin: 100px auto;
  transition: all 0.8s;
}
.oct:before,
.oct:after,
.oct span {
  content: "";
  position: absolute;
  height: inherit;
  width: inherit;
  background: inherit;
  -webkit-box-sizing: inherit;
  box-sizing: inherit;
  border: inherit;
  top: -10px;
  z-index:-1;
}
.oct:before {
  left: -100%;
  transform: rotate(-45deg);
  transform-origin: top right;
}
.oct:after {
  left: 100%;
  transform: rotate(45deg);
  transform-origin: top left;
}
.oct span {
  height: inherit;
  width: inherit;
  background: inherit;
  transform: rotate(90deg);
}
.oct:hover {
  transform: rotate(180deg);
}
<div class="oct">
  <span></span>
</div>
jbutler483
  • 24,074
  • 9
  • 92
  • 145
2

Imagine those red lines extending until they touch each other. That square (rotated 45%) has a complete border, you just don't see the "cut off" corners due to the overflow: hidden;

This seems to work (but does so by adding two extra divs, so there may be a better way):

<div class='octagonWrap'>
  <div class='octagon'></div>
  <div class='vert'> </div>
  <div class='hort'> </div>
</div>

and then add tihs css:

.vert {
     position: absolute;
     left: 60px;
     border-top: 3px solid red;
     border-bottom: 3px solid red;
     height: 194px;
     width: 80px;
 }
 .hort {
     position: absolute;
     top: 60px;
     border-left: 3px solid red;
     border-right: 3px solid red;
     width: 94px;
     height: 80px;
 }
John Hascall
  • 9,176
  • 6
  • 48
  • 72
1

You should try using the HTML5 canvas element. You should be able to draw the polygon and then add a stroke to it.

Community
  • 1
  • 1
mcphersonjr
  • 733
  • 12
  • 35
0

I saw such a code inside the Metronik theme code, and in my opinion, it was unmatched in terms of beauty, and you can also use it.

.octagon {clip-path: polygon(46.1731656763% .7612046749%,47.411809549% .3407417371%,48.6947380778% .0855513863%,50% 0,51.3052619222% .0855513863%,52.588190451% .3407417371%,53.8268343237% .7612046749%,82.1111055711% 12.4769334274%,83.2842712475% 13.0554747147%,84.3718855375% 13.7821953496%,85.3553390593% 14.6446609407%,86.2178046504% 15.6281144625%,86.9445252853% 16.7157287525%,87.5230665726% 17.8888944289%,99.2387953251% 46.1731656763%,99.6592582629% 47.411809549%,99.9144486137% 48.6947380778%,100% 50%,99.9144486137% 51.3052619222%,99.6592582629% 52.588190451%,99.2387953251% 53.8268343237%,87.5230665726% 82.1111055711%,86.9445252853% 83.2842712475%,86.2178046504% 84.3718855375%,85.3553390593% 85.3553390593%,84.3718855375% 86.2178046504%,83.2842712475% 86.9445252853%,82.1111055711% 87.5230665726%,53.8268343237% 99.2387953251% 52.588190451% 99.6592582629%,51.3052619222% 99.9144486137%,50% 100%,48.6947380778% 99.9144486137%,47.411809549% 99.6592582629%,46.1731656763% 99.2387953251%,17.8888944289% 87.5230665726%,16.7157287525% 86.9445252853%,15.6281144625% 86.2178046504%,14.6446609407% 85.3553390593%,13.7821953496% 84.3718855375%,13.0554747147% 83.2842712475%,12.4769334274% 82.1111055711%,.7612046749% 53.8268343237%,.3407417371% 52.588190451%,.0855513863% 51.3052619222%,0 50%,.0855513863% 48.6947380778%,.3407417371% 47.411809549%,.7612046749% 46.1731656763%,12.4769334274% 17.8888944289%,13.0554747147% 16.7157287525%,13.7821953496% 15.6281144625%,14.6446609407% 14.6446609407%,15.6281144625% 13.7821953496%,16.7157287525% 13.0554747147%,17.8888944289% 12.4769334274%);

You can also see the code that others are writing and it is working inside this page. I put the reference link here.