1

enter image description here

I want to make four angle borders for a div like the picture shows. I saw someone use <fieldset> to hide part of a border, but that's not what I want. Is there a simple way to achieve this?

JackJack
  • 612
  • 2
  • 12
  • 28
  • Is it acceptable to HIDE the background? Meaning the BG isn't transparent? If so its reasonably easy. – Bryce Howitson Oct 31 '18 at 20:42
  • 1
    A clean way (without pseudo elements or unnecessary markup) would be to use [CSS Border Image](https://developer.mozilla.org/en-US/docs/Web/CSS/border-image) with a source image that just has content for the corners. – Sean Oct 31 '18 at 20:57

3 Answers3

3

Use CSS Border Image with a source image that just has content for the corners. This avoids unnecessary html elements or pseudo elements. This example uses an SVG inlined into CSS as the source image.

.angled-borders {
  border: 10px solid;
  border-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 11' width='11' height='11'><g fill='%23489fe2'><rect width='1' height='5'/><rect y='6' width='1' height='5'/><rect x='10' y='6' width='1' height='5'/><rect x='10' width='1' height='5'/><rect width='5' height='1'/><rect y='10' width='5' height='1'/><rect x='6' y='10' width='5' height='1'/><rect x='6' width='5' height='1'/></g></svg>") 5;
}
div {
  display: inline-block;
  padding: 1rem;
}
<div class="angled-borders">content</div>

Edit: Escaped the hash in the data URI. Thanks, @AuxTaco.

Sean
  • 6,873
  • 4
  • 21
  • 46
  • 3
    [Make sure to escape the `#` in the data URI or Firefox will reject it.](https://stackoverflow.com/q/30733607/9029328) – AuxTaco Oct 31 '18 at 22:08
0

This is the case if background is not required to be transparent.

div{
  width: 100px;
  height: 50px;
  border: 2px solid blue;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  font-size: 30px;
  box-sizing: border-box;
}

div span{
  position: relative;
  z-index: 2;
}


div::before,
div::after{
  content: "";
  position: absolute;
  z-index: 1;
  background: #fff;
}

div::before{
  width: calc(100% + 4px);
  height: calc(100% - 20px);
  left: -2px;
}

div::after{
  width: calc(100% - 20px);
  height: calc(100% + 4px);
  left: 50%;
  transform: translateX(-50%);
}
<div>
  <span>
    1
  </span>
</div>
Kushtrim
  • 1,899
  • 6
  • 14
  • Check out my answer for a method that doesn't need extra elements or pseudo elements. – Sean Oct 31 '18 at 21:36
  • @sean yes, that works better. This was just one of the methods to achieve this results. Not sure why it was downvoted. – Kushtrim Nov 01 '18 at 08:01
0

If the background is a solid color (meaning you don't care about seeing through the element) you can do it reasonably easily.

Basically, we just lay pseudo elements over the top of the border with the same color as the background so the border appears hidden.

div.outer {
  width: 200px;
  height: 200px;
  box-shadow: 0 0 5px 0 rgba(0,0,0,0.2);
  /* keep absolute position childern in place */
  position:relative;
  
  /*full border*/
  border: 5px solid blue;

  /*background so we can see what happens*/
  background-color:#eee;
  }
 
 div.inner {
  line-height: 160px;
  padding: 20px;
  text-align: center;
  position: relative;
  z-index:10;
 }
 
 
 div.outer:before, div.outer:after {
  content:"";
  position: absolute;
 
  /*hide stuff*/
  background-color: #eee;
 }
 
 div.outer:before {
  top:-5px; /*width of border subtracted from top*/
  left:5%; /*push in 5% from the sides */
  bottom:-5px;
  right: 5%;
 }
  div.outer:after {
  top:5%; /*push in 5% from the sides */
  left:-5px; /*width of border subtracted from top*/
  bottom:5%;
  right: -5px;
 }
 
  
<div class="outer">
<!-- sadly we need two divs to move the content forward -->
  <div class="inner">
  Content
  </div>
</div>
Bryce Howitson
  • 7,339
  • 18
  • 40