zichyboy
zichyboy

Reputation: 185

Is there a way to make a custom border in CSS?

I was given this word document as a reference for what they want made into a ReactJS app (they didn't specify the language but that's ultimately what ended up being the thing I both knew and was most convenient). I am having no trouble making everything they asked for except for this one specific thing which is a border of a specific style.

This image is an example of the border they're looking for.

enter image description here

I can figure out how to make a dotted border and a dashed one but not one going between one and the other. Here's my CSS code so far:

.instructions {
  border-style: dashed;
  border-width: 2px;
  margin-right: 100px;
  box-sizing: border-box;
  padding: 10px;
}

Here's what it looks like when run:

enter image description here

Is there any way to make custom borders?

Upvotes: 2

Views: 11601

Answers (3)

amgg
amgg

Reputation: 604

SVG elements have the stroke-dasharray property, which can be used to make custom borders like that (in an svg).

<svg xmlns="http://www.w3.org/2000/svg" width="100px" height="100px">
    <rect x="0" y="0" width="100" height="100" fill="transparent" stroke="black" stroke-width="4px" stroke-dasharray="16 2 2 2" />
</svg>

in the above example all the sizes are hard coded, but they don't need to be. if you write an svg like this

<svg xmlns="http://www.w3.org/2000/svg" >
    <rect x="0%" y="0%" width="100%" height="100%" fill="transparent" stroke="black" stroke-width="4px" stroke-dasharray="16 2 2 2" />
</svg>

you can then use it as a background image in your html, and it will scale to fill whatever container you put it in.

to use it as a background image you can you can just save the svg file somewhere and reference it from your css the same way you would with any other image, or you can turn the svg into a data url (this tool is useful for that).

.demo_box {
  width: 300px;
  height: 80px;
}
.custom_svg_border {
  /* this border won't actually take up any space since it's a background image, so add some extra padding to account for that */
  padding: 2px;
  /* background-image: url("foo/bar/custom_border.svg"); */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='0%25' y='0%25' width='100%25' height='100%25' fill='transparent' stroke='black' stroke-width='4px' stroke-dasharray='16 2 2 2' /%3E%3C/svg%3E");
}
<div class="custom_svg_border demo_box">
  hello world
</div>

Upvotes: 7

Ghibran Aljabbar
Ghibran Aljabbar

Reputation: 87

The closest thing i got for you is this

     .instructions {
        width: 200px;
        height: 200px;
        left: 35px;
        top: 35px;
        position: absolute;
        background-color: lightblue;
        border: dashed 3px black;
      }
      .instructions::after {
        content: "";
        width: 100%;
        height: 100%;
        left: -3px;
        top: -3px;
        position: absolute;
        border: dotted 3px black;
      }
<div class="instructions">content</div>

Note that all three values border-width, top,and left need to be the same. for example if your border-width is 5px your top and left need to be set at -5px

Upvotes: 0

Alvaro Men&#233;ndez
Alvaro Men&#233;ndez

Reputation: 9012

It's impossible to do it with just css and, if possible, it will also be very hard to achieve with javascript.

Notice that if you get close, text with hypehns and dots won't be aligned vertically... It won't be aligned also if you use underscore.

Using an image as border is the way to go as they have already told you.

Asuming you still want to try this is what I would do as a start... good luck transforming the example with javascript, if you can you'll have quite a nice sucesfull career ahead:

* {box-sizing:border-box;}
.border-container {
  position:relative;
  width:500px;
  height:200px; 
  margin:0 auto;
}
.border-container:after {
  content:'_ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ .';
  overflow:hidden;
  width:100%;
  display:blocK;
  position:absolute;
  top:-18px;
  left:0;
  white-space:nowrap;
}
.border-container:before {
  content:'_ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ .';
  overflow:hidden;
  width:100%;
  display:blocK;
  position:absolute;
  bottom:0;
  left:0;
  white-space:nowrap;
}
.border-left {
  overflow: hidden;
    display: blocK;
    position: absolute;
    top: -20px;
    left: 0;
    white-space: nowrap;
    transform: rotate(90deg);
    width: 200px;
    transform-origin: bottom left;
}
.border-right {
  overflow: hidden;
    display: blocK;
    position: absolute;
    top: -20px;
    right:0;
    white-space: nowrap;
    transform: rotate(-90deg);
    width: 200px;
    transform-origin: bottom right;
}
<div class="border-container">
  <div class="border-left">
  _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ .
  </div> 
   <div class="border-right">
  _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ . _ .
  </div> 
 
</div> 

Upvotes: -2

Related Questions