Search code examples
htmlcsscss-shapes

How to add an offsetted outline to a CSS shape?


I have a bit of a problem with creating a block with beveled edges, in addition I need a border to be beveled and slightly off the main block. The problem is that this block can be Reponsive according to the screen.

I do not know the exact way to do it, hope everyone helps.

enter image description here

This is what I do now

.box {
  display: flex;
  padding: 20px;
  height: 200px;
  width: 300px;
  color: #ffffff;
  background: red;
  position: relative;
}

.box .edge {
  width: 18px;
  height: 10px;
  background: #ffffff;
  position: absolute;
}

.box .edge.top-left {
  top: -4px;
  left: -8px;
  transform: rotate(-45deg);
}

.box .edge.top-right {
  top: -4px;
  right: -8px;
  transform: rotate(45deg);
}

.box .edge.bottom-left {
  bottom: -4px;
  left: -8px;
  transform: rotate(45deg);
}

.box .edge.bottom-right {
  bottom: -4px;
  right: -8px;
  transform: rotate(-45deg);
}
<div class="box">
  <div class="edge top-left"></div>
  <div class="edge top-right"></div>
  <div class="edge bottom-left"></div>
  <div class="edge bottom-right"></div>
  <div class="content">
    content
  </div>
</div>


Solution

  • Here is an idea based on this previous answer. Simply adjust the different variables to get the result you want:

    .box {
      --c:10px; /* the corner */
      --b:3px;  /* border thickness*/
      --o:-10px,-15px; /* offset*/
      --border-color:green;
      --bg-color:red;
    
      width: 200px;
      height: 100px;
      display:inline-block;
      margin:30px;
      position:relative;
      z-index:0;
    }
    
    .box:before,
    .box:after{
      content:"";
      position:absolute;
      z-index:-1;
      top:0;
      left:0;
      right:0;
      bottom:0;
      clip-path: polygon(var(--c) 0%, calc(100% - var(--c)) 0%, 100% var(--c), 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, var(--c) 100%, 0% calc(100% - var(--c)), 0% var(--c));
      background:var(--bg-color);
    }
    
    .box:after {
      --grad:transparent 49.5%,var(--border-color) 50%;
      background: 
        linear-gradient(to top right   ,var(--grad)) top    right,
        linear-gradient(to top left    ,var(--grad)) top    left,
        linear-gradient(to bottom right,var(--grad)) bottom right,
        linear-gradient(to bottom left ,var(--grad)) bottom left;
      background-size:calc(var(--c) - var(--b)) calc(var(--c) - var(--b));
      background-repeat:no-repeat;
      border: var(--b) solid var(--border-color);
      transform:translate(var(--o));
    }
    <div class='box'></div>
    
    <div class='box' style="--c:40px;--b:2px;--o:10px,-20px;--border-color:blue;--bg-color:orange"></div>

    CSS Shape outline

    Works with image too:

    .box {
      --c:10px; /* the corner */
      --b:3px;  /* border thickness*/
      --o:-10px,-15px; /* offset*/
      --border-color:green;
      --bg-color:red;
    
      width: 200px;
      height: 100px;
      display:inline-block;
      margin:30px;
      position:relative;
      z-index:0;
    }
    
    .box:before,
    .box:after{
      content:"";
      position:absolute;
      z-index:-1;
      top:0;
      left:0;
      right:0;
      bottom:0;
      clip-path: polygon(var(--c) 0%, calc(100% - var(--c)) 0%, 100% var(--c), 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, var(--c) 100%, 0% calc(100% - var(--c)), 0% var(--c));
      background:url(https://picsum.photos/id/1069/800/800) center/cover;
    }
    
    .box:after {
      --grad:transparent 49.5%,var(--border-color) 50%;
      background: 
        linear-gradient(to top right   ,var(--grad)) top    right,
        linear-gradient(to top left    ,var(--grad)) top    left,
        linear-gradient(to bottom right,var(--grad)) bottom right,
        linear-gradient(to bottom left ,var(--grad)) bottom left;
      background-size:calc(var(--c) - var(--b)) calc(var(--c) - var(--b));
      background-repeat:no-repeat;
      border: var(--b) solid var(--border-color);
      transform:translate(var(--o));
    }
    <div class='box'></div>
    
    <div class='box' style="--c:40px;--b:2px;--o:10px,-20px;--border-color:blue;"></div>